复制文件可以用 CopyFile API 函数。CopyFileEx 函数的好处是:它提供了回调函数,程序员可以向用户显示复制的过程。
这里我不打算介绍回调函数的详细参数,这个可以看MSDN;我说一些MSDN中没有说明的东西。
1、多久回调一次?答案是:每传输 64KB 数据回调一次;
2、回调原因第一次返回:CALLBACK_STREAM_SWITCH ,以后都返回:CALLBACK_CHUNK_FINISHED
第一次表示开始复制,但还没有复制。
3、回调函数返回 PROGRESS_CONTINUE,表示继续复制文件;返回 PROGRESS_CANCEL,表示中断复制,这个比较有用。
上边都是理论,下面我们看一个例子,该例子为 VC++ 6.0 控制台工程。建立一个控制台工程,选择一个空的工程,建立一个 C++ 文件,把下面代码复制进去即可。
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
/**/
/*************************************************************/
//
//
CopyFileEx 回调函数应用
//
//
至尊宝宝 zaodt_ms@hotmail.com
//
//
2007-11-21
//
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
/**/
/*************************************************************/
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
#define
_WIN32_WINNT 0x0500
//
不加这个不同通过编译
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
#include
<
windows.h
>
#include
<
stdio.h
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
DWORD CALLBACK CopyProgress(
LARGE_INTEGER TotalFileSize,
//
total file size, in bytes
LARGE_INTEGER TotalBytesTransferred,
//
total number of bytes transferred
LARGE_INTEGER StreamSize,
//
total number of bytes for this stream
LARGE_INTEGER StreamBytesTransferred,
//
total number of bytes transferred for this stream
DWORD dwStreamNumber,
//
the current stream
DWORD dwCallbackReason,
//
reason for callback
HANDLE hSourceFile,
//
handle to the source file
HANDLE hDestinationFile,
//
handle to the destination file
LPVOID lpData
//
passed by CopyFileEx
)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
static int nRecord = 0;
nRecord++;
printf("回调次数:%d 已传输:%08X:%08X 文件大小:%08X:%08X ",
nRecord,
TotalBytesTransferred.HighPart,
TotalBytesTransferred.LowPart,
TotalFileSize.HighPart,
TotalFileSize.LowPart);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
return PROGRESS_CONTINUE;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
int
main(
int
argc,
char
*
argv[])
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
if(argc!=3)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
printf("用法:命令 源文件 目标文件");
return 0;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
if(!CopyFileEx(argv[1],argv[2],(LPPROGRESS_ROUTINE)CopyProgress,NULL,FALSE,COPY_FILE_FAIL_IF_EXISTS))
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
printf("CopyFileEx() failed.");
return 0;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
return 0;
}
运行结果:
回调次数:1 已传输:00000000:00000000 文件大小:00000000:00F60964
回调次数:2 已传输:00000000:00010000 文件大小:00000000:00F60964
回调次数:3 已传输:00000000:00020000 文件大小:00000000:00F60964
回调次数:4 已传输:00000000:00030000 文件大小:00000000:00F60964
回调次数:5 已传输:00000000:00040000 文件大小:00000000:00F60964
回调次数:6 已传输:00000000:00050000 文件大小:00000000:00F60964
回调次数:7 已传输:00000000:00060000 文件大小:00000000:00F60964
分析:
大家看第一次,已传输为0,从第二次开始,每次传输为 0x10000,为 64KB 字节。
如果您通过这篇文章明白了 CopyFileEx 的回调用法,请回帖,以资鼓励!