欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

总结几个处理文件夹的小程序

程序员文章站 2022-05-12 16:22:02
...

在处理文件夹时,我们需要用到一个结构体 struct _finddata_t,它包含在头文件 #include <io.h> 中, 相关的知识可以参看这篇博文_finddata_t结构体用法

需要的头文件

#include <io.h>
#include <fstream>
#include <string>
#include <vector>
#include <iostream>
#include <stdlib.h>
using namespace std;

 

1、批量获取指定文件夹下的所有文件(可能含子文件夹中的文件)的文件名,路径等,若我们把信息写到文件里,可用来生成列表文件

//获取所有的文件名
void GetAllFiles( string path, vector<string>& files)  
//path 为要进行查找的文件夹路径, files 用于存储文件夹下各文件的名称, 路径等信息
{  
	long   hFile   =   0;  
	//文件信息  
	struct _finddata_t fileinfo;//用来存储文件信息的结构体  
	string p;
	string q=path;

	if( ( hFile = _findfirst(p.assign(path).append("\\*").c_str(),&fileinfo) ) !=  -1)  
	//第一次查找,_findfirst是一个计算机函数,功能是搜索与指定的文件名称匹配的第一个实例
	//返回值:如果查找成功的话,将返回一个long型的唯一的查找用的句柄(就是一个唯一编号)
	//这个句柄将在_findnext函数中被使用。若失败,则返回-1 
	//函数原型是 long _findfirst( char *filespec, struct _finddata_t *fileinfo )
	//filespec:标明文件的字符串,可支持通配符,如:*.c,表示当前文件夹下所有后缀为 .c的文件 
	//fileinfo:用来存放文件信息的结构体的指针。这个结构体必须在调用此函数前声明
	//不过不用初始化,只要分配了内存空间就可以了
	//assign():C++ string 类的成员函数,用于拷贝、赋值操作
	//它允许我们顺次地把一个 string 对象的部分内容拷贝到另一个 string 对象上
	//p.assing(path),即把 path 这个字符串赋值给局部定义的字符串p
	//append():append函数是向string的后面追加字符或字符串, 把"\\*"追加给p
	//c_str():const char *c_str(); c_str()函数返回一个指向正规C字符串的指针常量 
	//内容与本string串相同,c_str是Borland封装的String类中的一个函数,它返回当前字符串的首字符地址
	{  
		do  
		{   
			if((fileinfo.attrib &  _A_SUBDIR))  //如果查找到的是文件夹
			{  
				if(strcmp(fileinfo.name,".") != 0  &&  strcmp(fileinfo.name,"..") != 0)  //进入文件夹查找
				{
					files.push_back(p.assign(path).append("\\").append(fileinfo.name) );
					//原路径多加了这个子文件夹的路径
					GetAllFiles( p.assign(path).append("\\").append(fileinfo.name), files ); //递归调用
				}
			}  
			else //如果查找到的不是是文件夹,即文件
			{  

				files.push_back( /*p.assign(fileinfo.name)+"   "   +   */  q.append("\\").append(fileinfo.name));  
				//将文件名和对应的路径写成一个字符串,保存到 vector 容器中
				//将文件路径保存,也可以只保存文件名:    q.assign(path).append("\\").append(fileinfo.name)
				q=path;//重新赋值,以备下个文件添加路径
			} 
 
		}while(_findnext(hFile, &fileinfo)  == 0);  
		//int _findnext( long handle, struct _finddata_t *fileinfo ); 
		//返回值:若成功返回0,否则返回-1。 
		//参数:handle:即由_findfirst函数返回回来的句柄。 
		//fileinfo:文件信息结构体的指针。找到文件后,函数将该文件信息放入此结构体中。
		//若查找到满足条件的文件,就继续查找
 
		_findclose(hFile); //结束查找
	} 
 
}  

2、批量获取指定文件夹下的指定格式的文件(可能含子文件夹中的文件)的文件名,路径等

void GetAllFormatFiles( string path, vector<string>& files, string format)  
{  
	//文件句柄  
	long   hFile   =   0;  
	//文件信息  
	struct _finddata_t fileinfo;  
	string p; 
	string q=path;
	if((hFile = _findfirst(p.assign(path).append("\\*" + format).c_str(),&fileinfo)) !=  -1)  
	{  
		do  
		{    
			if((fileinfo.attrib &  _A_SUBDIR))  
			{  
				if(strcmp(fileinfo.name,".") != 0  &&  strcmp(fileinfo.name,"..") != 0)  
				{
					//files.push_back(p.assign(path).append("\\").append(fileinfo.name) );
					GetAllFormatFiles( p.assign(path).append("\\").append(fileinfo.name), files,format); 
				}
			}  
			else  
			{  
				files.push_back( p.assign(fileinfo.name)+"     "+q.append("\\").append(fileinfo.name) );  
				q=path;
			}  
		}while(_findnext(hFile, &fileinfo)  == 0);  
 
		_findclose(hFile); 
	} 
} 

3、批量修改指定文件夹下的文件名称

我们经常会遇到一些情形,需要修改很多个文件的文件名,比如:

(1) 文件夹下有若干个格式为 .txt 的文本文件,现在要把它们的格式都改为 .lst

(2) 文件夹下是音频文件,每一个的命名形式为“歌名 + “-” + 歌手名”,现在要把它们的命名形式改成“歌手名 + “-” + 歌名”

(3) 文件夹下每个文件中都带有“0123”,想都替换成“ABCD”

这时,我们只需要调用前面的函数 GetAllFiles() 或 GetAllFormatFiles(), 余下的只是字符串的操作而已,我们这里以 (2) 为例给出源代码。操作前是这样的

 总结几个处理文件夹的小程序

void ChangeFileNames(string path, vector<string>& files)
{
	//调用函数获取所有的文件名,由于格式不固定,需要All
	GetAllFiles(path, files);

	vector<string>::iterator iter; //迭代计数器

	//遍历文件名向量,并进行修改
	for (iter = files.begin(); iter != files.end(); ++iter)      
	{
		string oldName = path + "\\" + *iter;  //歌曲的旧路径
		string singerName, songName;       //用于存储歌手名,歌曲名的字符串
		string songFormat;                 //歌曲文件格式
		int pos1 = 0, pos2 = 0;
		pos1 = (*iter).find_first_of(" - ");
		//获取歌手名和歌曲名的分隔符出现的位置
		pos2 = (*iter).find_last_of(".");
		//获取扩展名之前的“.”出现的位置
		//由pos1,pos2即可对字符串进行拆分

		songName = (*iter).substr(0,pos1);
		singerName = (*iter).substr(pos1+3,pos2-pos1-3);
		songFormat = (*iter).substr(pos2,(*iter).size()-pos2);
		string newName = path + "\\" + singerName + " - " + songName + songFormat;


		//以下开始重命名
		char *oldNamePointer = new char[oldName.size()+1];
		char *newNamePointer = new char[newName.size()+1];
		strcpy(oldNamePointer, oldName.c_str());
		strcpy(newNamePointer, newName.c_str());
		//cout<<oldNamePointer<<endl;
		//cout<<newNamePointer<<endl;
		rename(oldNamePointer, newNamePointer);
		//int rename(const char *oldname, const char *newname);


		delete []oldNamePointer;
		delete []newNamePointer;

		//以下是C语言形式的代码
		/*char *oldNamePointer, *newNamePointer;
		oldNamePointer = (char *)malloc((oldName.size()+1) * sizeof(char));
		newNamePointer = (char *)malloc((newName.size()+1) * sizeof(char));
		strcpy(oldNamePointer, oldName.c_str());
		strcpy(newNamePointer, newName.c_str());
		cout<<oldNamePointer<<endl;
		cout<<newNamePointer<<endl;
		rename(oldNamePointer, newNamePointer);
		free(oldNamePointer);
		free(newNamePointer);*/

	}

}

总结几个处理文件夹的小程序

我们把 main 函数的代码也给出

int main()
{
	string filePath_1 = "D:\\音乐";  
	vector<string> files_1;  
	ChangeFileNames(filePath_1, files_1);

	//读取所有的文件,包括子文件的文件
	string filePath_2 = "D:\\Sample\\WesternLtter\\Hungary";
	vector<string> files_2;  
	GetAllFiles(filePath_2, files_2);
	

	//读取所有格式为pot的文件
	//string format = ".pot";
	//GetAllFormatFiles(filePath, files, format);

	
	ofstream ofn(filePath_2 + "\\Hungary.lst");
	//在对应文件夹下创建列表

	if(!ofn)//检查是否打开成功
	{
        cout << "Failed to create file...\n";
        exit(0);
    }
	for (int i = 0; i < files_2.size(); i++)  
	{  
		ofn << files_2[i] << endl; // 写入列表文件
		//cout << files_2[i] << endl;//输出到屏幕
	}
	ofn.close();
	return 0;
}

4、批量处理文件夹中文件的内容

相关标签: 文件操作 实用