C/C++ 刪除文件夾以及文件夾裏的所有文件

一、開發環境

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 (非常感謝這位博主的文章,我在此基礎上做了一點封裝)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章