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

在处理文件夹时,我们需要用到一个结构体 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、批量处理文件夹中文件的内容

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值