C/C++中使用CopyFile、CopyFileEx原理、用法、区别及分别在哪些场景使用

embedded/2025/3/11 11:02:24/

文章目录

  • 1. CopyFile
    • 原理
    • 函数原型
    • 返回值
    • 用法示例
    • 适用场景
  • 2. CopyFileEx
    • 原理
    • 函数原型
    • 返回值
    • 用法示例
    • 适用场景
  • 3. 核心区别
  • 4. 选择建议
  • 5. 常见问题
  • 6.区别

在Windows系统编程中,CopyFileCopyFileEx是用于文件复制的两个API函数。它们的核心区别在于功能扩展性和控制粒度,以下是详细分析:


1. CopyFile

原理

  • 同步阻塞:函数调用后线程会阻塞,直到复制完成或失败。
  • 简单复制:仅复制文件内容,不支持进度回调或中断操作。
  • 原子性操作:直接覆盖或保留目标文件,无中间状态。

函数原型

BOOL CopyFile(LPCSTR  lpExistingFileName, // 源文件路径LPCSTR  lpNewFileName,      // 目标文件路径BOOL    bFailIfExists       // 目标存在时是否失败(TRUE=禁止覆盖)
);
  • lpExistingFileName: 指向一个以null结尾的字符串,指定要复制的现有文件的路径。
  • lpNewFileName: 指向一个以null结尾的字符串,指定新文件的路径。
  • bFailIfExists: 如果该参数为TRUE,并且目标文件已存在,则函数将失败。如果为FALSE,目标文件将被覆盖。

返回值

  • 如果函数成功,返回值为非零值。
  • 如果函数失败,返回值为零。可以使用GetLastError获取更多错误信息。

用法示例

#include <Windows.h>int main() {BOOL result = CopyFile("C:\\source.txt", "D:\\dest.txt", FALSE // 允许覆盖);if (!result) {DWORD error = GetLastError();// 处理错误...}return 0;
}

适用场景

  • 需要快速复制小文件。
  • 无需用户交互或进度反馈。
  • 简单工具或脚本中快速实现文件复制。

2. CopyFileEx

原理

  • 异步支持:通过回调函数支持进度跟踪和操作中断。
  • 扩展功能:支持重启复制(COPY_FILE_RESTARTABLE)、文件属性保留等。
  • 分块复制:可能通过多次调用回调函数分批次复制数据。

函数原型

BOOL CopyFileEx(LPCSTR             lpExistingFileName,LPCSTR             lpNewFileName,LPPROGRESS_ROUTINE lpProgressRoutine, // 进度回调函数LPVOID             lpData,            // 传递给回调的用户数据LPBOOL             pbCancel,          // 取消标志指针DWORD              dwCopyFlags        // 复制标志(如重启模式)
);
  • lpExistingFileName: 指向一个以null结尾的字符串,指定要复制的现有文件的路径。
  • lpNewFileName: 指向一个以null结尾的字符串,指定新文件的路径。
  • lpProgressRoutine: 指向一个进度例程的指针,该例程在复制过程中被调用,可以用于显示复制进度或允许用户取消操作。如果不需要进度例程,可以设置为NULL
  • lpData: 指向一个包含进度例程所需数据的指针,可以是NULL
  • pbCancel: 指向一个布尔值的指针,如果设置为TRUE,复制操作将被取消。可以是NULL
  • dwCopyFlags: 指定复制操作的选项,可以是以下值的组合:
    • COPY_FILE_FAIL_IF_EXISTS: 如果目标文件已存在,复制操作将失败。
    • COPY_FILE_RESTARTABLE: 创建可以恢复的复制操作。
    • COPY_FILE_OPEN_SOURCE_FOR_WRITE: 允许源文件在复制过程中被写入。
    • COPY_FILE_ALLOW_DECRYPTED_DESTINATION: 允许将未加密文件复制到未加密目标。
    • COPY_FILE_NO_BUFFERING: 复制操作是使用未缓冲的 I/O 执行,绕过系统 I/O 缓存资源。
    • COPY_FILE_COPY_SYMLINK: 如果源文件是符号链接,则目标文件也是指向源符号链接指向的同一文件的符号链接。
    • COPY_FILE_REQUEST_COMPRESSED_TRAFFIC: 请求基础传输通道在复制操作期间压缩数据。 对于所有媒体,请求可能不受支持,在这种情况下,它将被忽略。 压缩属性和参数(计算复杂性、内存使用情况)无法通过此 API 进行配置,并且可能会在不同的 OS 版本之间更改。。

返回值

  • 如果函数成功,返回值为非零值。
  • 如果函数失败,返回值为零。可以使用GetLastError获取更多错误信息。

用法示例

#include <Windows.h>DWORD CALLBACK ProgressCallback(LARGE_INTEGER TotalFileSize,LARGE_INTEGER TotalBytesTransferred,LARGE_INTEGER StreamSize,LARGE_INTEGER StreamBytesTransferred,DWORD dwStreamNumber,DWORD dwCallbackReason,HANDLE hSourceFile,HANDLE hDestinationFile,LPVOID lpData
) {// 显示进度百分比double progress = (double)TotalBytesTransferred.QuadPart / TotalFileSize.QuadPart * 100;printf("进度: %.2f%%\n", progress);return PROGRESS_CONTINUE; // 继续复制
}int main() {BOOL result = CopyFileEx("C:\\bigfile.iso","D:\\bigfile.iso",ProgressCallback,nullptr,        // 无额外数据传递nullptr,        // 不使用取消标志COPY_FILE_RESTARTABLE);if (!result) {DWORD error = GetLastError();// 处理错误...}return 0;
}

适用场景

  • 大文件复制需要显示实时进度条。
  • 允许用户取消长时间操作(如资源管理器中的文件复制)。
  • 需要断点续传功能的备份软件。

3. 核心区别

特性CopyFileCopyFileEx
进度反馈不支持支持通过回调函数
操作中断无法取消可通过回调返回值或取消标志终止
复制模式仅基础复制支持重启模式(COPY_FILE_RESTARTABLE
适用文件大小小文件(<100MB)大文件(如GB级)
复杂度简单,参数少复杂,需处理回调和标志位

4. 选择建议

  • 优先 CopyFile:当需求简单、无需额外控制时,代码更简洁高效。
  • 必须用 CopyFileEx:若需要以下高级功能:
    • 用户界面中的进度条更新。
    • 允许用户取消耗时操作。
    • 断点续传或错误恢复机制。
    • 复制文件时保留更多元数据(如ACL)。

5. 常见问题

  • 跨卷复制:两者均支持,但CopyFileEx可通过标志优化。
  • 错误处理:均需检查返回值并通过GetLastError()获取错误码。
  • Unicode支持:实际开发中应使用CopyFileW/CopyFileExW处理宽字符路径。

6.区别

  1. 参数类型

    • CopyFile使用的是LPCSTR类型的字符串,即ANSI字符串。
    • CopyFileEx使用的是LPCTSTR类型的字符串,可以是ANSI或Unicode字符串。
  2. 功能

    • CopyFile是一个简单的文件复制函数,适合快速复制文件。
    • CopyFileEx提供了更多的功能,如进度回调、取消复制等,适合需要更复杂控制的场景。
  3. 灵活性

    • CopyFileExCopyFile更灵活,可以处理更大的文件,并且可以提供复制进度的反馈。
  4. 适用场景

    • CopyFile:适用于简单的文件复制操作,不需要进度反馈或复杂控制。
    • CopyFileEx:适用于需要实时监控复制进度、允许用户取消操作或处理大文件的场景。

通过合理选择这两个API,可以在功能复杂性和代码效率之间取得平衡。


此后为废话,纯粹是为了应对csdn质量分,没有任何价值,不要浏览。
在这里插入图片描述
更多学习资料


无论代码世界如何复杂,请记住:每一个“复制”的瞬间,都是向目标更进一步的印记。即使遇到“错误”与“中断”,只要心怀“重启”的勇气,终将在调试中突破,在坚持中抵达。愿你在技术的长路上,像CopyFileEx一样永不止步,以智慧为引,以耐心为伴,书写属于你的完美程序!
🚀 代码无涯,行者无疆——你的下一行,或许就是改变世界的起点。


http://www.ppmy.cn/embedded/171735.html

相关文章

火语言RPA--PDF转Word

【组件功能】&#xff1a;PDF文档转换Word文档 配置预览 配置说明 文件路径 支持T或# 默认FLOW输入项 待转Word的PDF文件的完整路径。 PDF文件密码 支持T或# 打开PDF文件的密码。 Word文件保存至文件夹 支持T或# 将转换的Word文件保存至此文件夹。 Word文件格式 .doc和…

CI/CD—Jenkins配置Maven+GitLab自动构建jar包

一、安装Maven插件通过Maven构建项目 1、在Jenkins上安装Maven Integration plugin插件 2、创建一个maven项目 2.1、填写构建的名称和描述等 2.2、填写连接git的url 报错&#xff1a;无法连接仓库&#xff1a;Error performing git command: git ls-remote -h http://192.168.…

【贪心算法】简介

1.贪心算法 贪心策略&#xff1a;解决问题的策略&#xff0c;局部最优----》全局最优 &#xff08;1&#xff09;把解决问题的过程分成若干步 &#xff08;2&#xff09;解决每一步的时候&#xff0c;都选择当前看起来的“最优”的算法 &#xff08;3&#xff09;“希望”得…

从 Web2 到 Web3:互联网发展的重要转折

从 Web2 到 Web3&#xff1a;互联网发展的重要转折 随着互联网技术的飞速发展&#xff0c;我们正站在一个新时代的门槛上&#xff0c;即从 Web2 向 Web3 的转变。这一转变不仅仅是技术的升级&#xff0c;更是互联网理念和应用模式的一次重大革新。本文将探讨 Web2 和 Web3 的核…

Flutter底层实现

1. Dart 语言 Dart 是 Flutter 的主要编程语言。Dart 设计之初就是为了与 JavaScript 兼容&#xff0c;并且可以编译为机器代码运行。Dart 提供了一些特性&#xff0c;如异步支持&#xff08;通过 async 和 await&#xff09;&#xff0c;这使得编写高效的网络请求和复杂动画变…

JAVA面试_进阶部分_深入理解socket网络异常

在各种网络异常情况的背后&#xff0c;TCP是怎么处理的&#xff1f;又是怎样把处理结果反馈给上层应用的&#xff1f;本文就来讨论这个问题。 分为两个场景来讨论 建立连接 1 正常情况下 进过三次握手&#xff0c;客户端连接成功&#xff0c;服务端有一个新连接到来。 2 客…

Spring Boot 热部署

文章目录 一&#xff0c;Spring Boot热部署概述二&#xff0c;对项目HelloWorld01进行热部署 1、添加开发工具依赖2、热部署配置3、热部署测试 一&#xff0c;Spring Boot热部署概述 在开发过程中&#xff0c;通常会对一段业务代码不断地修改测试&#xff0c;在修改之后往往…

AWS AppStream 2.0:开启云端应用交付新范式(实战解决方案剖析)

导言&#xff1a;数字化转型中的"最后一公里"挑战 当企业加速上云进程时&#xff0c;CAD设计软件、财务系统等专业工具受制于终端性能、数据安全与跨平台难题。AWS AppStream 2.0作为全托管应用流服务&#xff0c;正为2000企业破解这一困局——无需代码改造&#xff…