首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Delphi快速文件复制

Delphi快速文件复制
EN

Stack Overflow用户
提问于 2009-01-13 08:01:18
回答 6查看 29.4K关注 0票数 16

我正在写一个应用程序,它可以把一堆文件从一个地方复制到另一个地方。当我使用TFileStream进行复制时,它比使用操作系统复制文件慢3-4倍。

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

我在Win32下工作,有人对这件事有什么见解吗?

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2009-01-13 08:28:42

这里有几个选项。

你可以调用CopyFile,它使用CopyFileA的windows API

  • ,你可以调用explorer使用的api ( windows api SHFileOperation。在SCIP.be
  • You上可以找到一个调用该函数的示例,它可以编写您自己的使用buffer.

的函数

如果你知道你要复制的文件类型,第三种方法通常会比其他方法更好。因为windows API针对整体最好的情况(小文件、大文件、网络文件、慢速驱动器上的文件)进行了更多的调整。您可以调整自己的复制功能来更好地满足您的需求。

下面是我自己的缓冲复制函数(我去掉了GUI回调):

代码语言:javascript
复制
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, 0, FILE_END);
    FileSeek(ASourceFile, 0, FILE_BEGIN);
    ADestinationFile :=  CreateLongFileName(ADestinationFileName, FILE_SHARE_READ);
    if ADestinationFile <> 0 then
    try
      while (FileSize - FileSeek(ASourceFile, 0, FILE_CURRENT)) >= BufferSize do
      begin
        if (not ReadFile(ASourceFile, Buffer[0], BufferSize, BytesRead, nil)) and (BytesRead = 0) then
         Continue;
        WriteFile(ADestinationFile, Buffer[0], BytesRead, BytesWritten, 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, 0, FILE_CURRENT)  < FileSize then
      begin
        if (not ReadFile(ASourceFile, Buffer[0], FileSize - FileSeek(ASourceFile, 0, FILE_CURRENT), BytesRead, nil)) and (BytesRead = 0) then
         ReadFile(ASourceFile, Buffer[0], FileSize - FileSeek(ASourceFile, 0, FILE_CURRENT), BytesRead, nil);
        WriteFile(ADestinationFile, Buffer[0], BytesRead, BytesWritten, nil);
        if BytesWritten < BytesRead then
        begin
          WriteFile(ADestinationFile, Buffer[BytesWritten], BytesRead - BytesWritten, BytesWritten2, nil);
          if (BytesWritten2 + BytesWritten) < BytesRead then
            RaiseLastOSError;
        end;
      end;
    finally
      CloseHandle(ADestinationFile);
    end;
  finally
    CloseHandle(ASourceFile);
  end;
end;

自己的函数:

代码语言:javascript
复制
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)), GENERIC_READ, SharingMode, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
end;
function OpenLongFileName(const ALongFileName: WideString; SharingMode: DWORD): THandle;  overload;
begin
  if CompareMem(@(WideCharToString(PWideChar(ALongFileName))[1]), @('\\'[1]), 2) then
    { Allready an UNC path }
    Result := CreateFileW(PWideChar(ALongFileName), GENERIC_READ, SharingMode, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)
  else
    Result := CreateFileW(PWideChar('\\?\' + ALongFileName), GENERIC_READ, SharingMode, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
end;

function CreateLongFileName(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_WRITE, SharingMode, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0)
  else
    Result := CreateFileW(PWideChar(WideString('\\?\' + ALongFileName)), GENERIC_WRITE, SharingMode, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
end;
function CreateLongFileName(const ALongFileName: WideString; SharingMode: DWORD): THandle; overload;
begin
  if CompareMem(@(WideCharToString(PWideChar(ALongFileName))[1]), @('\\'[1]), 2) then
    { Allready an UNC path }
    Result := CreateFileW(PWideChar(ALongFileName), GENERIC_WRITE, SharingMode, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0)
  else
    Result := CreateFileW(PWideChar('\\?\' + ALongFileName), GENERIC_WRITE, SharingMode, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
end;

代码比必要的要长一点,因为我包含了一个重试机制来支持我遇到的wifi连接问题。

所以这部分

代码语言:javascript
复制
    if BytesWritten < BytesRead then
    begin
      WriteFile(ADestinationFile, Buffer[BytesWritten], BytesRead - BytesWritten, BytesWritten2, nil);
      if (BytesWritten2 + BytesWritten) < BytesRead then
        RaiseLastOSError;
    end;

可以写成

代码语言:javascript
复制
    if BytesWritten < BytesRead then
    begin
        RaiseLastOSError;
    end;
票数 28
EN

Stack Overflow用户

发布于 2009-01-13 08:14:18

也许你可以研究一下科比安备份8(代号为黑月)的源代码。它是开源的,用Delphi编写。

http://www.educ.umu.se/~cobian/cobianbackup.htm

票数 4
EN

Stack Overflow用户

发布于 2014-08-20 18:21:48

首先,我很抱歉打断了这个老帖子,但我根据自己的需要对Davy Landman所做的伟大答案做了一些重要的修改。这些更改包括:

  • 添加了使用相对路径的可能性(当然,绝对路径和UNC路径支持保持不变)
  • 添加了回调功能,以便在屏幕上显示复制的进度(继续阅读)或取消复制过程
  • 主代码被清理了一点。我认为Unicode支持保留了,但我真的不知道,因为我使用的是Delphi编译器的最新ANSI版本(如果有人可以测试的话?)

要使用此代码,请在项目中创建一个FastCopy.pas文件,然后复制粘贴内容:

代码语言:javascript
复制
{
  FastCopyFile

  By SiZiOUS 2014, based on the work by Davy Landman
  www.sizious.com - @sizious - fb.com/sizious - sizious (at) gmail (dot) com

  This unit was designed to copy a file using the Windows API.
  It's faster than using the (old) BlockRead/Write and TFileStream methods.

  Every destination file will be overwritten (by choice), unless you specify
  the fcfmAppend CopyMode flag. In that case, the source file will be appened to
  the destination file (instead of overwriting it).

  You have the choice to use a normal procedure callback, method object callback
  or no callback at all. The callback is used to cancel the copy process and to
  display the copy progress on-screen.

  Developed and tested under Delphi 2007 (ANSI).
  If you are using a Unicode version of Delphi (greater than Delphi 2007), may
  be you need to do some adapations (beware of the WideString type).

  All credits flying to Davy Landman.
  http://stackoverflow.com/questions/438260/delphi-fast-file-copy   
}
unit FastCopy;

interface

uses
  Windows, SysUtils;

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

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

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

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

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

implementation

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

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

{ Dummy Callback: Classical Procedure Version }
procedure DummyCallback(const FileName: TFileName;
  const CurrentSize, TotalSize: LongWord; 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): Boolean; overload;
const
  BUFFER_SIZE = 524288; // 512KB blocks, change this to tune your speed

var
  Buffer: array of Byte;
  ASourceFile, ADestinationFile: THandle;
  FileSize, BytesRead, BytesWritten, BytesWritten2, TotalBytesWritten,
  CreationDisposition: LongWord;
  CanContinue, CanContinueFlag: Boolean;

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

  // 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, 0, FILE_END);
    FileSeek(ASourceFile, 0, FILE_BEGIN);

    // 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, 0, FILE_END);

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

        // Reading from source
        if (ReadFile(ASourceFile, Buffer[0], BUFFER_SIZE, 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 }
function FastCopyFile(const ASourceFileName, ADestinationFileName: TFileName;
  CopyMode: TFastCopyFileMode): Boolean; overload;
begin
  Result := FastCopyFile(ASourceFileName, ADestinationFileName, CopyMode,
    DummyCallback);
end;

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

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

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

end.

main方法称为FastCopyFile,您有4个重载函数来满足每个需求。下面你会找到两个例子,向你展示如何使用该单元。

第一种方法最简单:只需创建一个Console Application,然后复制粘贴以下内容:

代码语言:javascript
复制
program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  fastcopy in 'fastcopy.pas';

begin
  try
    WriteLn('FastCopyFile Result: ', FastCopyFile('test2.bin', 'test.bin'));
    WriteLn('Strike the <ENTER> key to exit...');
    ReadLn;
  except
    on E:Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;
end.

如果您愿意,我制作了一个VCL应用程序,以便向您展示如何显示复制进度和中止可能性。此应用程序是多线程的,以避免GUI冻结。要测试这个更完整的示例,请创建一个新的VCL应用程序,然后使用以下代码:

单元1.pas

代码语言:javascript
复制
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls, StdCtrls, ExtCtrls, FastCopy;

type
  TFastCopyFileThread = class;

  TForm1 = class(TForm)
    Button1: TButton;
    ProgressBar1: TProgressBar;
    Label1: TLabel;
    Button2: TButton;
    RadioGroup1: TRadioGroup;
    GroupBox1: TGroupBox;
    Edit1: TEdit;
    GroupBox2: TGroupBox;
    Edit2: TEdit;
    OpenDialog1: TOpenDialog;
    SaveDialog1: TSaveDialog;
    Button3: TButton;
    Button4: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
  private
    { Déclarations privées }
    fFastCopyFileThread: TFastCopyFileThread;
    fFastCopyFileThreadCanceled: Boolean;
    procedure ChangeControlsState(State: Boolean);
    procedure FastCopyFileProgress(Sender: TObject; FileName: TFileName;
      Value: Integer; var CanContinue: Boolean);
    procedure FastCopyFileTerminate(Sender: TObject);
    function GetStatusText: string;
    procedure SetStatusText(const Value: string);
  public
    { Déclarations publiques }
    procedure StartFastCopyThread;
    property StatusText: string read GetStatusText write SetStatusText;
  end;

  TFastCopyFileProgressEvent = procedure(Sender: TObject; FileName: TFileName;
    Value: Integer; var CanContinue: Boolean) of object;

  TFastCopyFileThread = class(TThread)
  private
    fSourceFileName: TFileName;
    fDestinationFileName: TFileName;
    fProgress: TFastCopyFileProgressEvent;
    fCopyMode: TFastCopyFileMode;
    procedure FastCopyFileCallback(const FileName: TFileName;
      const CurrentSize, TotalSize: LongWord; var CanContinue: Boolean);
  protected
    procedure Execute; override;
  public
    constructor Create; overload;
    property SourceFileName: TFileName
      read fSourceFileName write fSourceFileName;
    property DestinationFileName: TFileName
      read fDestinationFileName write fDestinationFileName;
    property CopyMode: TFastCopyFileMode read fCopyMode write fCopyMode;
    property OnProgress: TFastCopyFileProgressEvent
      read fProgress write fProgress;
  end;  

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
begin
  StartFastCopyThread;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  fFastCopyFileThread.Terminate;
  fFastCopyFileThreadCanceled := True;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
  with OpenDialog1 do
    if Execute then
      Edit1.Text := FileName;
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
  with SaveDialog1 do
    if Execute then
      Edit2.Text := FileName;
end;

procedure TForm1.ChangeControlsState(State: Boolean);
begin
  Button1.Enabled := State;
  Button2.Enabled := not State;
  if State then
  begin
    if fFastCopyFileThreadCanceled then
      StatusText := 'Aborted!'
    else
      StatusText := 'Done!';
    fFastCopyFileThreadCanceled := False;
  end;
end;

procedure TForm1.FastCopyFileProgress(Sender: TObject; FileName: TFileName;
  Value: Integer; var CanContinue: Boolean);
begin
  StatusText := ExtractFileName(FileName);
  ProgressBar1.Position := Value;
end;

procedure TForm1.FastCopyFileTerminate(Sender: TObject);
begin
  ChangeControlsState(True);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  ChangeControlsState(True);
  StatusText := 'Idle...';
end;

function TForm1.GetStatusText: string;
begin
  Result := Label1.Caption;
end;

procedure TForm1.SetStatusText(const Value: string);
begin
  Label1.Caption := Value;
end;

procedure TForm1.StartFastCopyThread;
begin
  ChangeControlsState(False);
  fFastCopyFileThread := TFastCopyFileThread.Create;
  with fFastCopyFileThread do
  begin
    SourceFileName := Edit1.Text;
    DestinationFileName := Edit2.Text;
    CopyMode := TFastCopyFileMode(RadioGroup1.ItemIndex);
    OnProgress := FastCopyFileProgress;
    OnTerminate := FastCopyFileTerminate;
    Resume;
  end;
end;

{ TFastCopyFileThread }

constructor TFastCopyFileThread.Create;
begin
  inherited Create(True);
  FreeOnTerminate := True;
end;

procedure TFastCopyFileThread.Execute;
begin
  FastCopyFile(SourceFileName, DestinationFileName, CopyMode,
    FastCopyFileCallback);
end;

procedure TFastCopyFileThread.FastCopyFileCallback(const FileName: TFileName;
  const CurrentSize, TotalSize: LongWord; var CanContinue: Boolean);
var
  ProgressValue: Integer;

begin
  CanContinue := not Terminated;
  ProgressValue := Round((CurrentSize / TotalSize) * 100);
  if Assigned(OnProgress) then
    OnProgress(Self, FileName, ProgressValue, CanContinue);
end;

end.

单元1.dfm

代码语言:javascript
复制
object Form1: TForm1
  Left = 0
  Top = 0
  BorderStyle = bsDialog
  Caption = 'FastCopyFile Example (Threaded)'
  ClientHeight = 210
  ClientWidth = 424
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  Position = poScreenCenter
  OnCreate = FormCreate
  PixelsPerInch = 96
  TextHeight = 13
  object Label1: TLabel
    Left = 8
    Top = 173
    Width = 31
    Height = 13
    Caption = 'Label1'
  end
  object Button1: TButton
    Left = 259
    Top = 177
    Width = 75
    Height = 25
    Caption = 'Start'
    Default = True
    TabOrder = 0
    OnClick = Button1Click
  end
  object ProgressBar1: TProgressBar
    Left = 8
    Top = 188
    Width = 245
    Height = 13
    TabOrder = 1
  end
  object Button2: TButton
    Left = 340
    Top = 177
    Width = 75
    Height = 25
    Caption = 'Stop'
    TabOrder = 2
    OnClick = Button2Click
  end
  object RadioGroup1: TRadioGroup
    Left = 4
    Top = 110
    Width = 410
    Height = 57
    Caption = ' Copy Mode: '
    ItemIndex = 0
    Items.Strings = (
      'Create (Overwrite destination)'
      'Append (Merge destination)')
    TabOrder = 3
  end
  object GroupBox1: TGroupBox
    Left = 4
    Top = 4
    Width = 412
    Height = 49
    Caption = ' Source: '
    TabOrder = 4
    object Edit1: TEdit
      Left = 8
      Top = 20
      Width = 369
      Height = 21
      TabOrder = 0
      Text = 'test.bin'
    end
    object Button3: TButton
      Left = 383
      Top = 20
      Width = 21
      Height = 21
      Caption = '...'
      TabOrder = 1
      OnClick = Button3Click
    end
  end
  object GroupBox2: TGroupBox
    Left = 4
    Top = 59
    Width = 412
    Height = 50
    Caption = ' Destination: '
    TabOrder = 5
    object Edit2: TEdit
      Left = 8
      Top = 21
      Width = 369
      Height = 21
      TabOrder = 0
      Text = 'sizious.bin'
    end
  end
  object Button4: TButton
    Left = 387
    Top = 80
    Width = 21
    Height = 21
    Caption = '...'
    TabOrder = 6
    OnClick = Button4Click
  end
  object OpenDialog1: TOpenDialog
    DefaultExt = 'bin'
    Filter = 'All Files (*.*)|*.*'
    Options = [ofHideReadOnly, ofFileMustExist, ofEnableSizing]
    Left = 344
    Top = 12
  end
  object SaveDialog1: TSaveDialog
    DefaultExt = 'bin'
    Filter = 'All Files (*.*)|*.*'
    Options = [ofOverwritePrompt, ofHideReadOnly, ofEnableSizing]
    Left = 344
    Top = 68
  end
end

当然,不要忘记将FastCopy.pas文件引用添加到该项目中。

你应该得到这样的信息:

选择一个源文件,一个目标文件,然后点击Start

当然,所有的荣誉都归功于Davy Landman

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/438260

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档