在我的应用程序中,我需要复制超过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;
答案 0 :(得分:10)
如上所述,绝对使用 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;
此函数会提示覆盖现有文件的提示(也许可以调整以跳过它),但用户可以选择“全部”,这样只需单击一次,更快,有一个进度条,可以如果需要取消。
答案 1 :(得分:7)
您可以使用SHFileOperation()
API调用,并在结构的文件名中使用通配符。这样一次调用就可以一次性复制所有文件。甚至可以显示进度(通过回调函数)并允许用户取消操作。
答案 2 :(得分:2)
我现在无法测试您的代码,但请查看更正的版本
// (!) 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;
答案 3 :(得分:0)
也许您可能会尝试将一堆文件读入内存,然后立即将它们全部写入磁盘(如XCOPY)。这可能在文件系统上更好。