在Windows下使用MFC/Win32 API进行文件夹内所有文件的复制操作,可以通过遍历目录中的文件并逐个复制来实现

系列文章目录

文章目录

前言

在Windows下使用MFC/Win32 API进行文件夹内所有文件的复制操作,可以通过遍历目录中的文件并逐个复制来实现。以下是一个简单的示例,代码设计用于递归复制整个目录结构,而您的需求是复制一个特定的文件(Game.locres)到另一个目录。当前代码尝试复制整个Game目录及其子目录,而不是单独的文件。因此,当尝试递归进入不存在的子目录时(例如Game\Game),程序会失败。

为了仅复制特定文件,您需要修改代码以直接处理文件而不是目录。以下是修改后的代码示例,它将只复制Game.locres文件到目标目录:

初始化变量

WIN32_FIND_DATA findData 存储查找结果的数据结构。

HANDLE hFind 存储查找句柄。

wchar_t szFullSrcPath[MAX_PATH] 和 wchar_t szFullDstPath[MAX_PATH] 分别用于构造完整的源路径和目标路径。

构建通配符搜索字符串

wcscpy_s(szFullSrcPath, pszSrcDir); 将源目录路径复制到 szFullSrcPath。

wcscat_s(szFullSrcPath, L"\*"); 在路径后面加上通配符 *,表示查找所有文件。

查找第一个文件

hFind = FindFirstFile(szFullSrcPath, &findData); 使用 FindFirstFile 函数查找第一个文件。

如果 hFind 返回 INVALID_HANDLE_VALUE,表示查找失败,直接返回 false。

遍历文件和目录

使用 do...while 循环遍历所有文件。

wcscmp 比较文件名,跳过当前目录 (.) 和父目录 (...)。

构造完整的源路径和目标路径。

如果是目录,则递归调用 CopyFolder 函数复制整个目录树。

如果是文件,则使用 SHFileOperation 函数复制单个文件。

FOF_NOCONFIRMATION 表示不提示用户确认,FOF_SILENT 表示静默操作。

关闭查找句柄

FindClose(hFind); 关闭查找句柄。

返回值

如果所有操作成功,返回 true;否则返回 false。

cpp 复制代码
#include <windows.h>
#include <Shlobj.h>
#include <wchar.h>
#include <iostream> // 用于控制台输出

// 函数声明
bool CopyFolder(const wchar_t* pszSrcDir, const wchar_t* pszDstDir);

int wmain()
{
	//wchar_t szSrcDir[MAX_PATH];
	//wchar_t szDstDir[MAX_PATH];

	 使用常量路径代替输入
	//const wchar_t* pszSrcDir = L"E:\\soui\\LocationalTool\\Localization\\";
	//const wchar_t* pszDstDir = L"E:\\soui\\LocationalTool\\dest\\";

	//if (CopyFolder(pszSrcDir, pszDstDir))
	//	wprintf(L"Directory copied successfully.\n");
	//else
	//	wprintf(L"Failed to copy directory.\n");

	//return 0;
	const wchar_t* pszSrcFile = L"E:\\soui\\LocationalTool\\Localization\\Game\\en\\Game.locres";
	const wchar_t* pszDstDir = L"E:\\soui\\LocationalTool\\dest\\";

	wchar_t szDstFile[MAX_PATH];
	wcscpy_s(szDstFile, pszDstDir);
	wcscat_s(szDstFile, L"Game.locres");

	if (CopyFileW(pszSrcFile, szDstFile, FALSE))
		wprintf(L"File copied successfully.\n");
	else
	{
		DWORD dwError = GetLastError();
		wprintf(L"Failed to copy file. Error: %lu\n", dwError);
	}

	return 0;
}

bool CopyFolder(const wchar_t* pszSrcDir, const wchar_t* pszDstDir)
{
	WIN32_FIND_DATA findData;
	HANDLE hFind = INVALID_HANDLE_VALUE;
	wchar_t szFullSrcPath[MAX_PATH];
	wchar_t szFullDstPath[MAX_PATH];

	// 构建通配符搜索字符串
	wcscpy_s(szFullSrcPath, pszSrcDir);
	wcscat_s(szFullSrcPath, L"*");

	// 检查源目录是否存在
	DWORD dwAttrib = GetFileAttributesW(pszSrcDir);
	if (dwAttrib == INVALID_FILE_ATTRIBUTES) {
		DWORD dwError = GetLastError();
		wprintf(L"Failed to get attributes for '%ls'. Error: %lu\n", pszSrcDir, dwError);
		return false;
	}
	if (!(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)) {
		wprintf(L"Source path '%ls' is not a directory.\n", pszSrcDir);
		return false;
	}

	// 创建目标目录
	if (!::CreateDirectoryW(pszDstDir, NULL) && GetLastError() != ERROR_ALREADY_EXISTS) {
		DWORD dwError = GetLastError();
		wprintf(L"Failed to create destination directory '%ls'. Error: %lu\n", pszDstDir, dwError);
		return false;
	}

	// 查找第一个文件
	hFind = FindFirstFile(szFullSrcPath, &findData);
	if (hFind == INVALID_HANDLE_VALUE) {
		DWORD dwError = GetLastError();
		wprintf(L"Failed to find files in '%ls'. Error: %lu\n", pszSrcDir, dwError);
		return false;
	}

	do {
		// 跳过"." 和 ".." 目录
		if (wcscmp(findData.cFileName, L".") != 0 &&
			wcscmp(findData.cFileName, L"..") != 0) {

			wprintf(L"Processing '%ls'\n", findData.cFileName); // 输出正在处理的文件/目录

			wcscpy_s(szFullSrcPath, pszSrcDir);
			wcscat_s(szFullSrcPath, L"\\");
			wcscat_s(szFullSrcPath, findData.cFileName);

			wcscpy_s(szFullDstPath, pszDstDir);
			wcscat_s(szFullDstPath, L"\\");
			wcscat_s(szFullDstPath, findData.cFileName);

			// 如果是目录,则递归复制
			if ((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) {
				wprintf(L"Recursive call for directory '%ls'\n", szFullSrcPath); // 输出递归调用信息
				if (!CopyFolder(szFullSrcPath, szFullDstPath))
					return false;
			}
			else { // 否则复制文件
				SHFILEOPSTRUCT fileOp = { 0 };
				fileOp.wFunc = FO_COPY;
				fileOp.pFrom = szFullSrcPath;
				fileOp.pTo = szFullDstPath;
				fileOp.fFlags = FOF_NOCONFIRMATION | FOF_SILENT;

				if (!SHFileOperation(&fileOp)) {
					DWORD dwError = GetLastError();
					wprintf(L"Failed to copy file '%ls' to '%ls'. Error: %lu\n", szFullSrcPath, szFullDstPath, dwError);
					return false;
				}
			}
		}
	} while (FindNextFile(hFind, &findData));

	FindClose(hFind);
	return true;
}
相关推荐
唐诺3 小时前
几种广泛使用的 C++ 编译器
c++·编译器
冷眼看人间恩怨4 小时前
【Qt笔记】QDockWidget控件详解
c++·笔记·qt·qdockwidget
红龙创客4 小时前
某狐畅游24校招-C++开发岗笔试(单选题)
开发语言·c++
Lenyiin4 小时前
第146场双周赛:统计符合条件长度为3的子数组数目、统计异或值为给定值的路径数目、判断网格图能否被切割成块、唯一中间众数子序列 Ⅰ
c++·算法·leetcode·周赛·lenyiin
Clockwiseee5 小时前
php伪协议
windows·安全·web安全·网络安全
yuanbenshidiaos6 小时前
c++---------数据类型
java·jvm·c++
十年一梦实验室6 小时前
【C++】sophus : sim_details.hpp 实现了矩阵函数 W、其导数,以及其逆 (十七)
开发语言·c++·线性代数·矩阵
taoyong0016 小时前
代码随想录算法训练营第十一天-239.滑动窗口最大值
c++·算法
这是我587 小时前
C++打小怪游戏
c++·其他·游戏·visual studio·小怪·大型·怪物
唐宋元明清21887 小时前
.NET 阻止系统睡眠/息屏
windows·电源