2012-06-14 87 views
1

我正在使用CopyFileEx API複製同步/備份實用程序(用Delphi編碼)中的文件。目標CopyFileEx文件大小

無論如何,我注意到在複製過程中(或剛開始複製時),通過資源管理器,目標文件的文件大小將佔用全部大小 - 就像它被完全複製一樣。

這是一個問題,如果程序崩潰或出於某種原因失敗。由於文件大小使得它看起來像文件被完全複製 - 當它不是。

有沒有辦法讓CopyFileEx/OS在更新文件大小的過程中進行更新,以反映實際複製了多少......或僅在最後更新它(直到它顯示爲零完成)。

我懷疑答案是否定的 - 如果有的話,任何人都可以推薦替代API做一個文件拷貝....需求是我需要獲得進度信息,也必須儘可能快。

回答

0

沒有辦法做到這一點。此功能的原因是它減少了磁盤碎片。

你需要推出自己的。這非常簡單。 CopyFile僅僅是一個緩衝的複製循環。

+0

正如我的想法 - 不幸的是滾動我自己的東西,我已經嘗試過,但它沒有使用CopyFileEx快。 – froudeg

+0

你可以發佈你的代碼嗎?嘗試使用緩衝區大小播放。嘗試8KB,64KB和1MB。 – usr

+0

也copyfileex複製文件屬性,時間戳和NTFS備用數據流等 - 我仍然需要的東西。 我試着用緩衝區大小的playin,但即使我得到它非常快,但不足以最大限度地發揮我的吉比特局域網 - 哪個copyfileex可以做。不幸的是,速度必須和操作系統一樣快......因爲應用程序的主要目的是高速同步/複製。 – froudeg

0

滾動你自己似乎是唯一的解決方案,因爲CopyFileEx將始終分配文件的所有空間,即使它沒有完成複製。

我在下面使用了一個簡單的createfile,readfile和writefile例程。爲了確保最大速度不中斷,例程應該在自己的線程中運行。

procedure AltFileCopy(const source, dest : String); 
var 
    sHandle, dHandle : THandle; 
    pBuffer : array[1..500000] of Byte; 
    dwBytesToRead : DWORD; 
    dwBytesRead : DWORD; 
    dwBytesWritten : DWORD; 
    Success : BOOL; 
    lpcontext : pointer; 
begin 
    try 
     sHandle := CreateFile(PChar(source),GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0); 
     dHandle := CreateFile(PChar(dest), GENERIC_WRITE, 0, nil, CREATE_ALWAYS, 0, 0); 

     if (sHandle <> INVALID_HANDLE_VALUE) and (dHandle <> INVALID_HANDLE_VALUE) then begin 
      dwBytesToRead := sizeof(pBuffer); 
      Repeat 
      begin 
       ReadFile(sHandle, pBuffer, dwBytesToRead, &dwBytesRead, nil); 
       WriteFile(dHandle, pBuffer, dwBytesRead, &dwBytesWritten, nil); 
      end; 
      Until (dwBytesRead <> dwBytesToRead); 
     end; 
    finally 
     CloseHandle(dHandle); 
     CloseHandle(sHandle); 
    end; 
end;