huanhai 发表于 2025-12-21 08:45:48

文件_复制(带进度回调)

有不懂的私信我


<火山程序 类型 = "通常" 版本 = 1 />

方法 文件_复制 <公开 类型 = 逻辑型 注释 = "复制文件,带进度百分比回调" 折叠>
参数 源文件路径 <类型 = 文本型 注释 = "源文件完整路径">
参数 目标文件路径 <类型 = 文本型 注释 = "目标文件完整路径">
参数 缓冲区大小 <类型 = 整数 注释 = "每次读写的缓冲区大小,默认64KB" @默认值 = 65536>
{
    变量 已复制大小 <类型 = 长整数>
    变量 文件总大小 <类型 = 长整数>
    变量 当前进度 <类型 = 整数>
    变量 上次进度 <类型 = 整数>

    // 使用Windows API进行文件复制
    @ HANDLE hSrcFile = INVALID_HANDLE_VALUE;
    @ HANDLE hDstFile = INVALID_HANDLE_VALUE;
    @ BOOL bResult = FALSE;
    @ BYTE* pBuffer = NULL;
    @ DWORD dwBytesRead = 0;
    @ DWORD dwBytesWritten = 0;
    @ LARGE_INTEGER liFileSize;
    @
    @ // 打开源文件
    @ CVolMem memSrc, memDst;
    @ const wchar_t* srcPath = @<源文件路径>.GetText();
    @ const wchar_t* dstPath = @<目标文件路径>.GetText();
    @
    @ hSrcFile = CreateFileW(srcPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    @ if (hSrcFile == INVALID_HANDLE_VALUE) {
    @   return FALSE;
    @ }
    @
    @ // 获取文件大小
    @ if (!GetFileSizeEx(hSrcFile, &liFileSize)) {
    @   CloseHandle(hSrcFile);
    @   return FALSE;
    @ }
    @ @<文件总大小> = liFileSize.QuadPart;
    @
    @ // 创建目标文件
    @ hDstFile = CreateFileW(dstPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    @ if (hDstFile == INVALID_HANDLE_VALUE) {
    @   CloseHandle(hSrcFile);
    @   return FALSE;
    @ }
    @
    @ // 分配缓冲区
    @ pBuffer = new BYTE[@<缓冲区大小>];
    @ if (!pBuffer) {
    @   CloseHandle(hSrcFile);
    @   CloseHandle(hDstFile);
    @   return FALSE;
    @ }
    @
    @ @<已复制大小> = 0;
    @ @<上次进度> = -1;
    @ bResult = TRUE;
    @
    @ // 循环读写
    @ while (ReadFile(hSrcFile, pBuffer, @<缓冲区大小>, &dwBytesRead, NULL) && dwBytesRead > 0) {
    @   if (!WriteFile(hDstFile, pBuffer, dwBytesRead, &dwBytesWritten, NULL) || dwBytesWritten != dwBytesRead) {
    @         bResult = FALSE;
    @         break;
    @   }
    @   @<已复制大小> += dwBytesWritten;
    @
    @   // 计算进度百分比
    @   if (@<文件总大小> > 0) {
    @         @<当前进度> = (int)((@<已复制大小> * 100) / @<文件总大小>);
    @         if (@<当前进度> != @<上次进度>) {
    @             @<上次进度> = @<当前进度>;

    // 调用进度回调
    文件复制进度回调 (当前进度, 已复制大小, 文件总大小)

    @         }
    @   }
    @ }
    @
    @ // 清理资源
    @ delete[] pBuffer;
    @ CloseHandle(hSrcFile);
    @ CloseHandle(hDstFile);
    @
    @ return bResult;

    返回 (真)
}

方法 文件复制进度回调 <公开 注释 = "文件复制进度回调,可重写此方法处理进度" 折叠>
参数 进度百分比 <类型 = 整数 注释 = "当前进度百分比 0-100">
参数 已复制大小 <类型 = 长整数 注释 = "已复制的字节数">
参数 文件总大小 <类型 = 长整数 注释 = "文件总字节数">
{
    // 默认实现:更新进度条和输出调试信息
    进度条1.位置 = 进度百分比
    标签1.标题 = "进度: " + 到文本 (进度百分比) + "%"
    调试输出 ("复制进度: " + 到文本 (进度百分比) + "% (" + 到文本 (已复制大小) + "/" + 到文本 (文件总大小) + ")")

    // 处理消息,保持界面响应
    @ MSG msg;
    @ while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
    @   TranslateMessage(&msg);
    @   DispatchMessage(&msg);
    @ }
}

aixunsoft 发表于 2025-12-22 22:51:57

感谢分享

山梦 发表于 6 天前

感谢分享

67564226 发表于 6 天前

感谢分享
页: [1]
查看完整版本: 文件_复制(带进度回调)