Win32API 進捗を確認しながらファイルのコピーを行う CopyFileEx, CopyProgressRoutine
進捗を確認しながらファイルのコピーを行うには、CopyFileEx()関数とCopyFileEx()関数の中から呼ばれるコールバック関数を用いる。
CopyFileExは以下のようなプロトタイプになっている。
BOOL CopyFileEx( LPCWSTR lpExistingFileName, // 既存ファイルの名前 LPCWSTR lpNewFileName, // 新規ファイルの名前 LPPROGRESS_ROUTINE lpProgressRoutine, // コールバック関数 LPVOID lpData, // コールバック関数に渡す LPBOOL pbCancel, // 操作の取り消しに使う DWORD dwCopyFlags // ファイルのコピー方法を指定する );
さらに、LPPROGRESS_ROUTINE型は以下のように定義されている。この関数が、ファイルのコピー中に呼ばれることでファイルコピーの進捗を確認することができる。
DWORD CALLBACK CopyProgressRoutine( LARGE_INTEGER TotalFileSize, // バイト単位の総ファイルサイズ LARGE_INTEGER TotalBytesTransferred, // 転送された総バイト数 LARGE_INTEGER StreamSize, // このストリームの総バイト数 LARGE_INTEGER StreamBytesTransferred, // このストリームに対して転送された // 総バイト数 DWORD dwStreamNumber, // 現在のストリーム DWORD dwCallbackReason, // CopyProgressRoutine 関数が呼び出された理由 HANDLE hSourceFile, // コピー元ファイルのハンドル HANDLE hDestinationFile, // コピー先ファイルのハンドル LPVOID lpData // CopyFileEx 関数から渡される );
CopyFileExのサンプルコードは以下の通り。
#include <windows.h> #include <stdio.h> //CopyFileExで使われるコールバック関数 DWORD CALLBACK CopyProgressRoutine( LARGE_INTEGER TotalFileSize,// バイト単位の総ファイルサイズ LARGE_INTEGER TotalBytesTransferred,// 転送された総バイト数 LARGE_INTEGER StreamSize,// このストリームの総バイト数 LARGE_INTEGER StreamBytesTransferred,// このストリームに対して転送された総バイト数 DWORD dwStreamNumber,// 現在のストリーム DWORD dwCallbackReason,// CopyProgressRoutine 関数が呼び出された理由 HANDLE hSourceFile, // コピー元ファイルのハンドル HANDLE hDestinationFile, // コピー先ファイルのハンドル LPVOID lpData)// CopyFileEx 関数から渡される { puts("--------------------------------------------------"); printf("TotalFileSize = %u[B]\n", TotalFileSize.LowPart); printf("TotalBytesTransferred = %u[B]\n", TotalBytesTransferred.LowPart); printf("StreamSize = %u[B]\n", StreamSize.LowPart); printf("StreamBytesTransferred = %u[B]\n", StreamBytesTransferred.LowPart); printf("dwStreamNumber = %u\n", dwStreamNumber); if (dwCallbackReason == CALLBACK_CHUNK_FINISHED) { printf("dwCallbackReason = CALLBACK_CHUNK_FINISHED\n"); } else if (dwCallbackReason == CALLBACK_STREAM_SWITCH) { printf("dwCallbackReason = CALLBACK_STREAM_SWITCH\n"); } putchar('\n'); return 0; } int main(int argc, _TCHAR* argv[]) { BOOL bCancel = FALSE; CopyFileEx( "src.txt", // 既存ファイルの名前 "dst.txt", // 新規ファイルの名前 CopyProgressRoutine, // コールバック関数 NULL, // コールバック関数に渡す &bCancel, // 操作の取り消しに使う(キャンセルする際は、bCancelをTRUEにする) COPY_FILE_RESTARTABLE);// ファイルのコピー方法を指定する puts("Finished"); return 0; }
約2MBのファイルをコピーした実行結果は以下のようになった。
-------------------------------------------------- TotalFileSize = 2003328[B] TotalBytesTransferred = 0[B] StreamSize = 2003328[B] StreamBytesTransferred = 0[B] dwStreamNumber = 1 dwCallbackReason = CALLBACK_STREAM_SWITCH -------------------------------------------------- TotalFileSize = 2003328[B] TotalBytesTransferred = 262144[B] StreamSize = 2003328[B] StreamBytesTransferred = 262144[B] dwStreamNumber = 1 dwCallbackReason = CALLBACK_CHUNK_FINISHED -------------------------------------------------- TotalFileSize = 2003328[B] TotalBytesTransferred = 524288[B] StreamSize = 2003328[B] StreamBytesTransferred = 524288[B] dwStreamNumber = 1 dwCallbackReason = CALLBACK_CHUNK_FINISHED -------------------------------------------------- TotalFileSize = 2003328[B] TotalBytesTransferred = 786432[B] StreamSize = 2003328[B] StreamBytesTransferred = 786432[B] dwStreamNumber = 1 dwCallbackReason = CALLBACK_CHUNK_FINISHED -------------------------------------------------- TotalFileSize = 2003328[B] TotalBytesTransferred = 1048576[B] StreamSize = 2003328[B] StreamBytesTransferred = 1048576[B] dwStreamNumber = 1 dwCallbackReason = CALLBACK_CHUNK_FINISHED -------------------------------------------------- TotalFileSize = 2003328[B] TotalBytesTransferred = 1310720[B] StreamSize = 2003328[B] StreamBytesTransferred = 1310720[B] dwStreamNumber = 1 dwCallbackReason = CALLBACK_CHUNK_FINISHED -------------------------------------------------- TotalFileSize = 2003328[B] TotalBytesTransferred = 1572864[B] StreamSize = 2003328[B] StreamBytesTransferred = 1572864[B] dwStreamNumber = 1 dwCallbackReason = CALLBACK_CHUNK_FINISHED -------------------------------------------------- TotalFileSize = 2003328[B] TotalBytesTransferred = 1835008[B] StreamSize = 2003328[B] StreamBytesTransferred = 1835008[B] dwStreamNumber = 1 dwCallbackReason = CALLBACK_CHUNK_FINISHED -------------------------------------------------- TotalFileSize = 2003328[B] TotalBytesTransferred = 2003328[B] StreamSize = 2003328[B] StreamBytesTransferred = 2003328[B] dwStreamNumber = 1 dwCallbackReason = CALLBACK_CHUNK_FINISHED Finished
参考
http://msdn.microsoft.com/ja-jp/library/cc429187.aspx
http://msdn.microsoft.com/ja-jp/library/cc429191.aspx