本程序使用vs2013环境简单实现一个文件夹及其内容的递归复制功能。其中使用了结构体struct _finddata_t来保存文件的各种信息,用于判断及操作文件,这个结构体中有一些描述文件属性的成员,这里不作一一介绍,只介绍本程序用到的一个成员
attrib,其表示文件的属性:_A_ARCH(存档)、_A_HIDDEN(隐藏)、_A_NORMAL(正常)、_A_RDONLY(只读)、 _A_SUBDIR(文件夹)、_A_SYSTEM(系统)。配合这个结构体一起使用的函数有三个,long _findfirst(char*filepath,struct _finddata_t *fileinfo)、int _findnext(long handle,struct _finddata_t *fileinfo)和int _findclose(long handle),函数的具体作用及使用方法后面介绍。另外本程序中还使用到了int _access(const char *pathname, int mode)用于判断文件夹是否存在,当文件夹不存在时使用int _mkdir(const char *dirname)函数创建一个文件夹。
};
功能:保存文件的属性及相关信息。
功能:
返回唯一标识文件的文件句柄,并获取文件的属性信息保存到_finddata_t结构体中。
参数:
filepath:文件的路径(绝对路径形式的字符串)
fileinfo:结构体_finddata_t的指针,用于返回filepath所表示的文件的文件属性(如文件夹、文件、创建时间等)
返回值:
函数执行成功会返回一个唯一表示该文件的文件句柄(用于作为_findnext和_findclose的参数,进一步对文件进行处理)
执行成功同时还会把文件的具体属性信息保存到fileinfo这个结构体中。
功能:
寻找文件句柄handle所表示文件的同级目录中的下一个文件,若文件存在把该文件的信息属性保存到一个_finddata_t结构体中,并返回0,若失败返回-1。
参数:
handle:文件句柄,这个文件句柄是_findfirst函数返回的文件句柄。_findnext根据这个句柄查找下一个文件。
fileinfo:_finddata_t结构体指针,用于保存本函数所找到文件的文件信息。
返回值:
返回0表示成功,返回-1表示失败
功能:
成个文件查找过程结束,调用此函数关闭文件,释放资源。
参数:
handle:由_findfirst函数返回的文件句柄。
返回值:
成功返回0,失败返回-1。
功能:
当pathname(用绝对路径表示)所表示的为文件时会判断文件是否存在并判断该文件是否拥有mode所表示的访问权限。如果pathname所表示的是文件夹时,只判断文件夹是否存在。
参数:
pathname:表示文件的文件名,使用绝对路径表示。
mode:文件拥有的访问权限,0表示只检查文件是否存在包括对文件夹的检查,2表示检查文件是否拥有写权限,4检查文件的读权限,6检查文件是否拥有读和写权限。
返回值:
成功返回0,失败返回-1
功能:
创建一个文件夹(目录)
参数:
dirname:文件夹名,使用绝对路径表示。
返回值:
成功返回0,失败返回-1
注意:_finddata_t结构体及配套使用的三个函数和_access函数包含在
#include
#include
#include
#include
#include
using namespace std;
void CopyFiles(string &srcPath, string &desPath)
{
if (srcPath == "")
{
return;
}
char buf[100] = { 0 };
_finddata_t FileInfo;
string startFindPath = srcPath + "\\*";
long handle = _findfirst(startFindPath.c_str(), &FileInfo); //
if (handle == -1L)
{
return;
}
do{
if (FileInfo.attrib == _A_SUBDIR) //判断是否为子文件夹
{
if ((strcmp(FileInfo.name, ".") != 0) && (strcmp(FileInfo.name, "..") != 0)) //过滤掉本代表本目录的.和上一级目录的..
{
cout << "subdir:" << FileInfo.name << endl;
string newPath = srcPath + "\\" + FileInfo.name;
string newdesPath = desPath + "\\" + FileInfo.name;
if (_access(newdesPath.c_str(), 0) == -1) //判断组合好的目录是否已经存在,不存在则创建
{
_mkdir(newdesPath.c_str());
}
CopyFiles(newPath, newdesPath);
}
}
else
{
string srcFilePath = srcPath + "\\" + FileInfo.name;
string desFilePath = desPath + "\\" + FileInfo.name;
ifstream fin(srcFilePath, ios::_Nocreate | ios::binary);
ofstream fout(desFilePath, ios::binary);
if (!fin){
cout << "源文件路径没有找到:" << srcFilePath << endl;
continue;
}
if (!fout){
cout << "打开或者创建文件失败:" << desFilePath << endl;
continue;
}
while (!fin.eof())
{
fin.read(buf, sizeof(buf));
fout.write(buf, sizeof(buf));
}
cout << srcFilePath << endl;
}
} while (_findnext(handle, &FileInfo) == 0);
_findclose(handle);
}
void main()
{
string src = "";
string des = "";
cout << "请输入源文件路径:" << endl;
getline(cin, src);
cout << "请输入目标路径:" << endl;
getline(cin, des);
CopyFiles(src, des);
system("pause");
}