Delphi快速文件复制

前端之家收集整理的这篇文章主要介绍了Delphi快速文件复制前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在写一个应用程序,它应该将一堆文件从一个地方复制到另一个地方。
当我使用TFileStream进行复制时,比使用操作系统复制文件要慢3-4倍。

我也试图用缓冲区复制,但是也太慢了。

我正在Win32工作,任何人都有这方面的见解?

解决方法

有几个选择。

>你可以调用使用的CopyFile
CopyFileA windows API

>你可以调用浏览器使用的api(windows api
SHFileOperation)。一个例子
调用函数可以找到
SCIP.be
>你可以编写自己的使用缓冲区的函数

如果您知道要复制的文件类型,则第3种方法通常会胜过其他方式。因为Windows API更适合整体最佳情况(小文件,大文件,网络上的文件,慢驱动器上的文件)。您可以根据需要调整自己的复印功能

以下是我自己的缓冲复制功能(我已经删除GUI回调):

procedure CustomFileCopy(const ASourceFileName,ADestinationFileName: TFileName);
const
  BufferSize = 1024; // 1KB blocks,change this to tune your speed
var
  Buffer : array of Byte;
  ASourceFile,ADestinationFile: THandle;
  FileSize: DWORD;
  BytesRead,BytesWritten,BytesWritten2: DWORD;
begin
  SetLength(Buffer,BufferSize);
  ASourceFile := OpenLongFileName(ASourceFileName,0);
  if ASourceFile <> 0 then
  try
    FileSize := FileSeek(ASourceFile,FILE_END);
    FileSeek(ASourceFile,FILE_BEGIN);
    ADestinationFile :=  CreateLongFileName(ADestinationFileName,FILE_SHARE_READ);
    if ADestinationFile <> 0 then
    try
      while (FileSize - FileSeek(ASourceFile,FILE_CURRENT)) >= BufferSize do
      begin
        if (not ReadFile(ASourceFile,Buffer[0],BufferSize,BytesRead,nil)) and (BytesRead = 0) then
         Continue;
        WriteFile(ADestinationFile,nil);
        if BytesWritten < BytesRead then
        begin
          WriteFile(ADestinationFile,Buffer[BytesWritten],BytesRead - BytesWritten,BytesWritten2,nil);
          if (BytesWritten2 + BytesWritten) < BytesRead then
            RaiseLastOSError;
        end;
      end;
      if FileSeek(ASourceFile,FILE_CURRENT)  < FileSize then
      begin
        if (not ReadFile(ASourceFile,FileSize - FileSeek(ASourceFile,FILE_CURRENT),nil)) and (BytesRead = 0) then
         ReadFile(ASourceFile,nil);
        WriteFile(ADestinationFile,nil);
          if (BytesWritten2 + BytesWritten) < BytesRead then
            RaiseLastOSError;
        end;
      end;
    finally
      CloseHandle(ADestinationFile);
    end;
  finally
    CloseHandle(ASourceFile);
  end;
end;

自己的功能

function OpenLongFileName(const ALongFileName: String; SharingMode: DWORD): THandle; overload;
begin
  if CompareMem(@(ALongFileName[1]),@('\\'[1]),2) then
    { Allready an UNC path }
    Result := CreateFileW(PWideChar(WideString(ALongFileName)),GENERIC_READ,SharingMode,nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0)
  else
    Result := CreateFileW(PWideChar(WideString('\\?\' + ALongFileName)),0);
end;
function OpenLongFileName(const ALongFileName: WideString; SharingMode: DWORD): THandle;  overload;
begin
  if CompareMem(@(WideCharToString(PWideChar(ALongFileName))[1]),2) then
    { Allready an UNC path }
    Result := CreateFileW(PWideChar(ALongFileName),0)
  else
    Result := CreateFileW(PWideChar('\\?\' + ALongFileName),0);
end;

function CreateLongFileName(const ALongFileName: String; SharingMode: DWORD): THandle; overload;
begin
  if CompareMem(@(ALongFileName[1]),GENERIC_WRITE,CREATE_ALWAYS,0);
end;
function CreateLongFileName(const ALongFileName: WideString; SharingMode: DWORD): THandle; overload;
begin
  if CompareMem(@(WideCharToString(PWideChar(ALongFileName))[1]),0);
end;

代码有一点需要,因为我包括一个重试机制来支持我有一个wifi连接问题。

所以这部分

if BytesWritten < BytesRead then
    begin
      WriteFile(ADestinationFile,nil);
      if (BytesWritten2 + BytesWritten) < BytesRead then
        RaiseLastOSError;
    end;

可以写成

if BytesWritten < BytesRead then
    begin
        RaiseLastOSError;
    end;
原文链接:https://www.f2er.com/delphi/103242.html

猜你在找的Delphi相关文章