总结几个处理文件夹的小程序
程序员文章站
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、批量处理文件夹中文件的内容
上一篇: 文件操作IO流——File类