2012-06-14 47 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;