Копирование большого количества файлов в Delphi
в моем приложении мне нужно скопировать более 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 ответов
обязательно сходите с 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;
эта функция вызовет запрос на перезапись существующих файлов (возможно, ее можно настроить, чтобы пропустить это), но пользователь может выбрать "все", поэтому это процедура с одним щелчком мыши, много быстрее, имеет индикатор выполнения и может быть отменен при желании.
можно использовать SHFileOperation()
вызов API и использование подстановочного знака в имени файла структуры. Таким образом, один вызов будет использоваться для копирования всех файлов за один раз. Существует даже возможность показать прогресс (через функцию обратного вызова) и позволить пользователю отменить операцию.
Я не могу проверить ваш код прямо сейчас, но проверить это исправлено версия
// (!) 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;
возможно, вы могли бы поэкспериментировать с чтением кучу файлов в память, а затем записать их все на диск сразу (например, XCOPY). Это может быть лучше в файловой системе.