AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

FileCopy im Thread

Ein Thema von cramer · begonnen am 17. Mai 2017 · letzter Beitrag vom 17. Mai 2017
 
SneakyBagels
(Gast)

n/a Beiträge
 
#6

AW: FileCopy im Thread

  Alt 17. Mai 2017, 14:46
Hier mal meine Unit die ich schon ewig verwende und ein wenig angepasst habe und irgendwo mal gefunden habe.

Delphi-Quellcode:
unit uFastFileCopy;

interface

uses
 Windows, SysUtils;

type
 TFastCopyFileMode = (fcfmCreate, fcfmAppend);
 TFastCopyFileNormalCallback = procedure(const FileName: TFileName; const CurrentSize, TotalSize: Int64; var CanContinue: Boolean);
 TFastCopyFileMethodCallback = procedure(const FileName: TFileName; const CurrentSize, TotalSize: Int64; var CanContinue: Boolean) of object;

const
 BufferSize_Default: Cardinal = 4096 * 3 * 2;

 // Simplest definition
function FastCopyFile(const ASourceFileName, ADestinationFileName: TFileName): Boolean; overload;

// Definition with CopyMode and without any callbacks and default buffer
function FastCopyFile(const ASourceFileName, ADestinationFileName: TFileName; CopyMode: TFastCopyFileMode): Boolean; overload;

// Definition with normal procedure callback and default buffer
function FastCopyFile(const ASourceFileName, ADestinationFileName: TFileName; CopyMode: TFastCopyFileMode; Callback: TFastCopyFileNormalCallback): Boolean; overload;

// Definition with normal procedure callback and custom buffer
function FastCopyFile(const ASourceFileName, ADestinationFileName: TFileName; CopyMode: TFastCopyFileMode; Callback: TFastCopyFileNormalCallback; BufferSize: Cardinal)
 : Boolean; overload;

// Definition with object method callback and custom buffer
function FastCopyFile(const ASourceFileName, ADestinationFileName: TFileName; CopyMode: TFastCopyFileMode; Callback: TFastCopyFileMethodCallback; BufferSize: Cardinal)
 : Boolean; overload;

implementation

{Dummy Callback: Method Version}
type
 TDummyCallBackClient = class(TObject)
 private
  procedure DummyCallback(const FileName: TFileName; const CurrentSize, TotalSize: Int64; var CanContinue: Boolean);
 end;

procedure TDummyCallBackClient.DummyCallback(const FileName: TFileName; const CurrentSize, TotalSize: Int64; var CanContinue: Boolean);
begin
 // Nothing
 CanContinue := True;
end;

{Dummy Callback: Classical Procedure Version}
procedure DummyCallback(const FileName: TFileName; const CurrentSize, TotalSize: Int64; var CanContinue: Boolean);
begin
 // Nothing
 CanContinue := True;
end;

{CreateFileW API abstract layer}
function OpenLongFileName(ALongFileName: string; DesiredAccess, ShareMode, CreationDisposition: LongWord): THandle;
var
 // IsUNC: Boolean;
 FileName: PWideChar;

begin
 // Translate relative paths to absolute ones
 ALongFileName := ExpandFileName(ALongFileName);

 // Check if already an UNC path
 // IsUNC := Copy(ALongFileName, 1, 2) = '\\';
 // if not IsUNC then
 // ALongFileName := '\\?\' + ALongFileName;

 // Preparing the FileName for the CreateFileW API call
 FileName := PWideChar(WideString(ALongFileName));

 // Calling the API
 Result := CreateFileW(FileName, DesiredAccess, ShareMode, nil, CreationDisposition, FILE_ATTRIBUTE_NORMAL, 0);
end;

{FastCopyFile implementation}
function FastCopyFile(const ASourceFileName, ADestinationFileName: TFileName; CopyMode: TFastCopyFileMode; Callback: TFastCopyFileNormalCallback; Callback2: TFastCopyFileMethodCallback;
 BufferSize: Cardinal): Boolean; overload;
var
 Buffer: TArray<Byte>;
 ASourceFile, ADestinationFile: THandle;
 FileSize, TotalBytesWritten: Int64;
 BytesRead, BytesWritten, BytesWritten2, CreationDisposition: LongWord;
 CanContinue, CanContinueFlag: Boolean;

begin
 FileSize := 0;
 TotalBytesWritten := 0;
 CanContinue := True;
 SetLength(Buffer, BufferSize);

 // Manage the Creation Disposition flag
 CreationDisposition := CREATE_ALWAYS;
 if CopyMode = fcfmAppend then
  CreationDisposition := OPEN_ALWAYS;

 // Opening the source file in read mode
 ASourceFile := OpenLongFileName(ASourceFileName, GENERIC_READ, 0, OPEN_EXISTING);
 if ASourceFile <> 0 then
  try
   FileSize := FileSeek(ASourceFile, Int64(0), FILE_END);
   FileSeek(ASourceFile, Int64(0), FILE_BEGIN);

   SysUtils.ForceDirectories(ExtractFilePath(ADestinationFileName));

   // Opening the destination file in write mode (in create/append state)
   ADestinationFile := OpenLongFileName(ADestinationFileName, GENERIC_WRITE, FILE_SHARE_READ, CreationDisposition);

   if ADestinationFile <> 0 then
    try
     // If append mode, jump to the file end
     if CopyMode = fcfmAppend then
      FileSeek(ADestinationFile, Int64(0), FILE_END);

     // For each blocks in the source file
     while CanContinue and (FileSeek(ASourceFile, Int64(0), FILE_CURRENT) < FileSize) do
      begin

       // Reading from source
       if (ReadFile(ASourceFile, Buffer[0], BufferSize, BytesRead, nil)) and (BytesRead <> 0) then
        begin
         // Writing to destination
         WriteFile(ADestinationFile, Buffer[0], BytesRead, BytesWritten, nil);

         // Read/Write secure code block (e.g. for WiFi connections)
         if BytesWritten < BytesRead then
          begin
           WriteFile(ADestinationFile, Buffer[BytesWritten], BytesRead - BytesWritten, BytesWritten2, nil);
           Inc(BytesWritten, BytesWritten2);
           if BytesWritten < BytesRead then
            RaiseLastOSError;
          end;

         // Notifying the caller for the current state
         Inc(TotalBytesWritten, BytesWritten);
         CanContinueFlag := True;
         if Assigned(Callback) then
          Callback(ASourceFileName, TotalBytesWritten, FileSize, CanContinueFlag);
         CanContinue := CanContinue and CanContinueFlag;
         if Assigned(Callback2) then
          Callback2(ASourceFileName, TotalBytesWritten, FileSize, CanContinueFlag);
         CanContinue := CanContinue and CanContinueFlag;
        end;

      end;

    finally
     CloseHandle(ADestinationFile);
    end;

  finally
   CloseHandle(ASourceFile);
  end;

 // Check if cancelled or not
 if not CanContinue then
  if FileExists(ADestinationFileName) then
   DeleteFile(ADestinationFileName);

 // Results (checking CanContinue flag isn't needed)
 Result := (FileSize <> 0) and (FileSize = TotalBytesWritten);
end;

{FastCopyFile simple definition}
function FastCopyFile(const ASourceFileName, ADestinationFileName: TFileName): Boolean; overload;
begin
 Result := FastCopyFile(ASourceFileName, ADestinationFileName, fcfmCreate);
end;

{FastCopyFile definition without any callbacks and default buffer}
function FastCopyFile(const ASourceFileName, ADestinationFileName: TFileName; CopyMode: TFastCopyFileMode): Boolean; overload;
begin
 Result := FastCopyFile(ASourceFileName, ADestinationFileName, CopyMode, DummyCallback, BufferSize_Default);
end;

{Definition with normal procedure callback and default buffer}
function FastCopyFile(const ASourceFileName, ADestinationFileName: TFileName; CopyMode: TFastCopyFileMode; Callback: TFastCopyFileNormalCallback): Boolean; overload;
begin
 Result := FastCopyFile(ASourceFileName, ADestinationFileName, CopyMode, DummyCallback, BufferSize_Default);
end;

{FastCopyFile definition with normal procedure callback and custom buffer}
function FastCopyFile(const ASourceFileName, ADestinationFileName: TFileName; CopyMode: TFastCopyFileMode; Callback: TFastCopyFileNormalCallback; BufferSize: Cardinal)
 : Boolean; overload;
var
 DummyObj: TDummyCallBackClient;

begin
 DummyObj := TDummyCallBackClient.Create;
 try
  Result := FastCopyFile(ASourceFileName, ADestinationFileName, CopyMode, Callback, DummyObj.DummyCallback, BufferSize);
 finally
  DummyObj.Free;
 end;
end;

{FastCopyFile definition with object method callback and custom buffer}
function FastCopyFile(const ASourceFileName, ADestinationFileName: TFileName; CopyMode: TFastCopyFileMode; Callback: TFastCopyFileMethodCallback; BufferSize: Cardinal)
 : Boolean; overload;
begin
 Result := FastCopyFile(ASourceFileName, ADestinationFileName, CopyMode, DummyCallback, Callback, BufferSize);
end;

end.
Aufruf zum Beispiel mit Callback
Delphi-Quellcode:
procedure FileCopyCallBack(const FileName: TFileName; const CurrentSize, TotalSize: Int64; var CanContinue: Boolean);
begin
 CanContinue := PruefeX_Y_Z;
end;

if FileSize < 4096 * 50 then
 BufferSize := iFileSize
else
 BufferSize := 4096 * 50;

if FastCopyFile(sSource, sDest, TFastCopyFileMode.fcfmCreate, FileCopyCallBack, BufferSize) then
 ....
Geht sicher noch schneller aber ich finde es gut soweit.

Original hier: http://stackoverflow.com/questions/4...fast-file-copy

Geändert von SneakyBagels (17. Mai 2017 um 14:49 Uhr)
  Mit Zitat antworten Zitat
 

 

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:32 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz