文件夹的操作,是我们在编程中经常遇到的问题,在linux上和windows上经常会有文件夹操作的需求,典型的例子如遍历文件夹中的所有文件,在这两个系统中文件夹操作所提供的API也有所不同。
最近我老婆向我提了一个需求,便于她管理文件夹:开发一个exe,将exe放入一个目录下,点击该exe,生成这个目录下所有文件的清单,文件夹用“【】”括起来,同时根据文件级别进行缩进。
最近我老婆向我提了一个需求,便于她管理文件夹:开发一个exe,将exe放入一个目录下,点击该exe,生成这个目录下所有文件的清单,文件夹用“【】”括起来,同时根据文件级别进行缩进。
这个需求实现起来不难,用到的知识就是文件夹的遍历,在windows上使用的是windows相关的API函数,主要有用到FindFirstFile、FindNextFile、FindClose三个函数,存储文件或文件夹信息的结构体为WIN32_FIND_DATA,里面存储了文件类型(文件或文件夹)、文件名、文件大小、访问时间等信息。
在此记录此程序,方便后面查阅。
需求在windows下实现如下:
void GenerateList(FILE *file, const char *szDirPath, int nLevel)
{
BOOL bFind = TRUE;
WIN32_FIND_DATA fileData;
char szOldCurDir[MAX_PATH];
GetCurrentDirectory(sizeof(szOldCurDir), szOldCurDir);/* 获取当前工作目录,用于后面还原工作目录 */
SetCurrentDirectory(szDirPath);/* 设置当前工作目录 */
HANDLE hFind = FindFirstFile("*", &fileData);
if (hFind == INVALID_HANDLE_VALUE){
SetCurrentDirectory(szOldCurDir);/* 还原工作目录 */
return;
}
while (bFind){
if (fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY){/* 表示是文件夹 */
if (strcmp(fileData.cFileName, ".") == 0
|| strcmp(fileData.cFileName, "..") == 0){/* 找到当前文件夹或者上一级文件夹 */
bFind = FindNextFile(hFind, &fileData);
}
else{
fprintf(file, "%*s【%s】\r\n", 4 * nLevel, "", fileData.cFileName);
GenerateList(file, fileData.cFileName, nLevel + 1);
}
}
else {/* 普通文件 */
fprintf(file, "%*s%s\r\n", 4 * nLevel, "", fileData.cFileName);
}
bFind = FindNextFile(hFind, &fileData);
}
SetCurrentDirectory(szOldCurDir);/* 还原工作目录 */
FindClose(hFind);
}
int _tmain(int argc, _TCHAR* argv[])
{
FILE *file;
fopen_s(&file, "文件清单.txt", "wb");
if (file == NULL){
return -1;
}
GenerateList(file, ".", 0);
fclose(file);
return 0;
}
生成的文件清单: