一、開發環境
Visual Studio 2017 + win10
二、代碼
說明:調用 DeleteAllFile 函數會刪除此文件夾以及該文件夾裏的所有文件(具體調用方式參照示例程序)
//判斷是否是".."目錄和"."目錄
static bool IsSpecialDir(const char *path)
{
return strcmp(path, "..") == 0 || strcmp(path, ".") == 0;
}
//判斷文件屬性是目錄還是文件
static bool IsDir(int attrib)
{
return attrib == 16 || attrib == 18 || attrib == 20;
}
//顯示刪除失敗原因
static void ShowError(const char *file_name = NULL)
{
errno_t err;
_get_errno(&err);
switch (err)
{
case ENOTEMPTY:
printf("Given path is not a directory, the directory is not empty, or the directory is either the current working directory or the root directory.\n");
break;
case ENOENT:
printf("Path is invalid.\n");
break;
case EACCES:
printf("%s had been opend by some application, can't delete.\n", file_name);
break;
}
}
static void GetFilePath(const char *path, const char *file_name, char *file_path)
{
strcpy_s(file_path, sizeof(char) * _MAX_PATH, path);
file_path[strlen(file_path) - 1] = '\0';
strcat_s(file_path, sizeof(char) * _MAX_PATH, file_name);
}
//遞歸搜索目錄中文件並刪除
static void DeleteFile(const char *path)
{
char pcSearchPath[_MAX_PATH];
sprintf_s(pcSearchPath, _MAX_PATH, "%s\\*", path); //pcSearchPath 爲搜索路徑,* 代表通配符
_finddata_t DirInfo; //文件夾信息
_finddata_t FileInfo; //文件信息
intptr_t f_handle; //查找句柄
char pcTempPath[_MAX_PATH];
if ((f_handle = _findfirst(pcSearchPath, &DirInfo)) != -1)
{
while (_findnext(f_handle, &FileInfo) == 0)
{
if (IsSpecialDir(FileInfo.name))
continue;
if (FileInfo.attrib & _A_SUBDIR)//如果是目錄,生成完整的路徑
{
GetFilePath(pcSearchPath, FileInfo.name, pcTempPath);
DeleteFile(pcTempPath); //開始遞歸刪除目錄中的內容
if (FileInfo.attrib == 20)
printf("This is system file, can't delete!\n");
else
{
//刪除空目錄,必須在遞歸返回前調用_findclose,否則無法刪除目錄
if (_rmdir(pcTempPath) == -1)
{
ShowError();//目錄非空則會顯示出錯原因
}
}
}
else
{
strcpy_s(pcTempPath, pcSearchPath);
pcTempPath[strlen(pcTempPath) - 1] = '\0';
strcat_s(pcTempPath, FileInfo.name);//生成完整的文件路徑
if (remove(pcTempPath) == -1)
{
ShowError(FileInfo.name);
}
}
}
_findclose(f_handle);//關閉打開的文件句柄,並釋放關聯資源,否則無法刪除空目錄
}
else
{
ShowError();//若路徑不存在,顯示錯誤信息
}
}
void DeleteAllFile(const char* pcPath)
{
DeleteFile(pcPath); //刪除該文件夾裏的所有文件
if (_rmdir(pcPath) == -1) //刪除此文件夾
{
ShowError();
}
}
三、示例
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <io.h>
#include <direct.h>
#include <errno.h>
//判斷是否是".."目錄和"."目錄
static bool IsSpecialDir(const char *path)
{
return strcmp(path, "..") == 0 || strcmp(path, ".") == 0;
}
//判斷文件屬性是目錄還是文件
static bool IsDir(int attrib)
{
return attrib == 16 || attrib == 18 || attrib == 20;
}
//顯示刪除失敗原因
static void ShowError(const char *file_name = NULL)
{
errno_t err;
_get_errno(&err);
switch (err)
{
case ENOTEMPTY:
printf("Given path is not a directory, the directory is not empty, or the directory is either the current working directory or the root directory.\n");
break;
case ENOENT:
printf("Path is invalid.\n");
break;
case EACCES:
printf("%s had been opend by some application, can't delete.\n", file_name);
break;
}
}
static void GetFilePath(const char *path, const char *file_name, char *file_path)
{
strcpy_s(file_path, sizeof(char) * _MAX_PATH, path);
file_path[strlen(file_path) - 1] = '\0';
strcat_s(file_path, sizeof(char) * _MAX_PATH, file_name);
}
//遞歸搜索目錄中文件並刪除
static void DeleteFile(const char *path)
{
char pcSearchPath[_MAX_PATH];
sprintf_s(pcSearchPath, _MAX_PATH, "%s\\*", path); //pcSearchPath 爲搜索路徑,* 代表通配符
_finddata_t DirInfo; //文件夾信息
_finddata_t FileInfo; //文件信息
intptr_t f_handle; //查找句柄
char pcTempPath[_MAX_PATH];
if ((f_handle = _findfirst(pcSearchPath, &DirInfo)) != -1)
{
while (_findnext(f_handle, &FileInfo) == 0)
{
if (IsSpecialDir(FileInfo.name))
continue;
if (FileInfo.attrib & _A_SUBDIR)//如果是目錄,生成完整的路徑
{
GetFilePath(pcSearchPath, FileInfo.name, pcTempPath);
DeleteFile(pcTempPath); //開始遞歸刪除目錄中的內容
if (FileInfo.attrib == 20)
printf("This is system file, can't delete!\n");
else
{
//刪除空目錄,必須在遞歸返回前調用_findclose,否則無法刪除目錄
if (_rmdir(pcTempPath) == -1)
{
ShowError();//目錄非空則會顯示出錯原因
}
}
}
else
{
strcpy_s(pcTempPath, pcSearchPath);
pcTempPath[strlen(pcTempPath) - 1] = '\0';
strcat_s(pcTempPath, FileInfo.name);//生成完整的文件路徑
if (remove(pcTempPath) == -1)
{
ShowError(FileInfo.name);
}
}
}
_findclose(f_handle);//關閉打開的文件句柄,並釋放關聯資源,否則無法刪除空目錄
}
else
{
ShowError();//若路徑不存在,顯示錯誤信息
}
}
void DeleteAllFile(const char* pcPath)
{
DeleteFile(pcPath); //刪除該文件夾裏的所有文件
if (_rmdir(pcPath) == -1) //刪除此文件夾
{
ShowError();
}
}
int main(int argc, char **argv)
{
DeleteAllFile("D:\\test"); //會刪除 test 文件夾以及文件夾裏的所有文件
system("pause");
return 0;
}
四、參考
https://blog.csdn.net/sunshihua12829/article/details/45916225 (非常感謝這位博主的文章,我在此基礎上做了一點封裝)