代码之家  ›  专栏  ›  技术社区  ›  Charles Faiga

在Delphi中复制大量文件

  •  6
  • Charles Faiga  · 技术社区  · 17 年前

    在我的应用程序中,我需要复制1000多个小文件

    这是我正在使用的代码,但速度很慢 有更好的方法吗?

    procedure Tdatafeeds.RestotreTodaysFiles;
    var
      SearchRec: TSearchRec;
      FromFn, ToFn: string;
    Begin
        if DirectoryExists(BackupPath1) then
        begin
          try
            if FindFirst(BackupPath1 + '\*.*', (faAnyFile AND NOT(faDirectory)), SearchRec) = 0 then
            begin
              repeat
                FromFn := BackupPath1 + '\' + SearchRec.name;
                ToFn := DatafeedsPath1 + '\' + SearchRec.name;
                CopyFile(Pchar(FromFn), Pchar(ToFn), false);
              until FindNext(SearchRec) <> 0;
            end;
          finally
            FindClose(SearchRec);
          end;
        end;
    End;
    
    4 回复  |  直到 17 年前
        1
  •  10
  •   EagleOfToledo    17 年前

    当然可以 shfileoperation()。 如上所述,对于这么多的文件,copyfile的速度太慢了。看起来您基本上是在恢复整个文件夹,因此搜索功能可能是不必要的,并且会进一步降低速度。类似这样的情况可能会有所帮助:

    uses ShellApi;
    
    function CopyDir(const fromDir, toDir: string): Boolean;
    var
      fos: TSHFileOpStruct;
    begin
      ZeroMemory(@fos, SizeOf(fos));
      with fos do
      begin
        wFunc  := FO_COPY;
        fFlags := FOF_FILESONLY;
        pFrom  := PChar(fromDir + #0);
        pTo    := PChar(toDir)
      end;
      Result := (0 = ShFileOperation(fos));
    end;
    

    此函数将提示覆盖现有文件(可能可以调整跳过此操作),但用户可以选择“全部”,因此这是一个单击过程,速度更快,有一个进度条,可以根据需要取消。

        2
  •  7
  •   mghie    17 年前

    你可以使用 SHFileOperation() API调用并在结构的文件名中使用通配符。这样一次调用就可以一次复制所有文件。甚至有可能显示进度(通过回调函数),并允许用户取消操作。

        3
  •  2
  •   mghie    17 年前

    我现在不能测试你的代码,但是看看这个 修正的 版本

        // (!) faAnyFile-faDirectory <--- this is wrong
        // we don't subtract flag values because the value will be meaningless
        if FindFirst(BackupPath1 + '\*.*', faAnyFile, SearchRec) = 0 then
        begin
          repeat
            if  not (SearchRec.Attr and faDirectory)
                And SearchRec.Name <> "."
                And SearchRec.Name <> ".." Then
            Begin
              FromFn := BackupPath1 + '\' + SearchRec.name;
              ToFn := DatafeedsPath1 + '\' + SearchRec.name;
              CopyFile(Pchar(FromFn), Pchar(ToFn), false);
            End;
          until FindNext(SearchRec) <> 0;
          FindClose(SearchRec);
        end;
    
        4
  •  0
  •   Anthony Mills    17 年前

    也许您可以尝试将一组文件读取到内存中,然后将它们同时写入磁盘(如xcopy)。这在文件系统上可能更好。