Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.145.156.46] |
|
Сообщ.
#1
,
|
|
|
Мне нужно какой-либо способ копирование, перемещения и удаления файлов и папок, чтобы при этом я мог знать статус копирования (сколько процентов всего откопировалось, и сколько процентов откопировалось данного файла если я копирую директорию).
Ниже я привожу код копирования файла методом TFileStream. Как мне с помощью него откопировать целую папку(я пробовал вызывать процедуру рекурсивно, но прога вылетала после копирования 2000 файлов)? Если можно обойтись без этого способа, то подскажите как это сделать! Пример копирования файлов (TFileStream) в потоке (TThread). Компилятор: Delphi unit copythread; interface uses Classes, SysUtils; Const KB1 = 1024; MB1 = 1024*KB1; GB1 = 1024*MB1; type TCopyFile = class(TThread) public Percent : Integer; Done,ToDo : Integer; Start : TDateTime; constructor Create(Src, Dest: String); private { Private declarations } IName,OName : String; protected procedure Execute; override; end; implementation { TCopyFile } constructor TCopyFile.Create(Src, Dest : String); begin IName := Src; OName := Dest; Percent := 0; Start := Now; FreeOnTerminate := True; inherited Create(True); end; procedure TCopyFile.Execute; var fi,fo : TFileStream; dod,did : Integer; cnt,max : Integer; begin Start := Now; try { Открываем существующий путь } fo := TFileStream.Create(OName, fmOpenReadWrite); fo.Position:=fo.size; except { иначе создаём путь } fo := TFileStream.Create(OName, fmCreate); end; try { открываем копируемый файл } fi := TFileStream.Create(IName, fmOpenRead); try { синхронизируем } cnt:= fo.Position; fi.Position := cnt; max := fi.Size; ToDo := Max-cnt; Done := 0; { начинаем копирование } Repeat dod := MB1; // Block size if cnt+dod>max then dod := max-cnt; if dod>0 then did := fo.CopyFrom(fi, dod); cnt:=cnt+did; Percent := Round(Cnt/Max*100); Done := Done+did; ToDo := Max; until (dod=0) or (Terminated); finally fi.free; end; finally fo.free; end; end; end. Как использовать: begin ... TCopyFile.Create('d:\sourcfile.dat','d:\destination.dat'); ... end; |
Сообщ.
#2
,
|
|
|
Heretic2, в FAQ есть алгоритм перебора всех файлов во всех директориях рекурсивно.
Используй его и для каждого выполняй процедуру копирования файла. |
Сообщ.
#3
,
|
|
|
Цитата Heretic2,9.01.05, 23:27 @ Мне нужно какой-либо способ копирование, перемещения и удаления файлов и папок, чтобы при этом я мог знать статус копирования (сколько процентов всего откопировалось, и сколько процентов откопировалось данного файла если я копирую директорию). Тебе для чего эта информация нужна?? Только для отображения? Если да, то все это умеет ShFileOperation(в тоом числе и копировать папки целиком). Кроме того есть функция CopyFileEx, которая через callback функцию извещает о процессе копирования.. |
Сообщ.
#4
,
|
|
|
Цитата Heretic2, в FAQ есть алгоритм перебора всех файлов во всех директориях рекурсивно. Используй его и для каждого выполняй процедуру копирования файла. Я так уже пробовал и у меня прога вылетает, если в папке 2000 или более файлов. Цитата Тебе для чего эта информация нужна?? Только для отображения? Если да, то все это умеет ShFileOperation(в тоом числе и копировать папки целиком). Кроме того есть функция CopyFileEx, которая через callback функцию извещает о процессе копирования.. Как это всё работает, ф то я сам разбирался и у меня нифига не получилось |
Сообщ.
#5
,
|
|
|
var FromDir, ToDir: string; soo: TSHFileOpStruct; begin if SelectDirectory('From:', '', FromDir) and SelectDirectory('To:', '', ToDir) then begin ZeroMemory(@soo, SizeOf(soo)); soo.pFrom := PChar(FromDir + #0); soo.pTo := PChar(ToDir + #0); soo.wFunc := FO_COPY; ShFileOperation(soo); end; end; а с CopyFileEx уж сам постарайся ;-) |
Сообщ.
#6
,
|
|
|
А как мне узнать сколко процентов выполнено?
|
Сообщ.
#7
,
|
|
|
Цитата Heretic2 @ 10.01.05, 14:27 А как мне узнать сколко процентов выполнено? Цитата jack128 @ 10.01.05, 02:36 а с CopyFileEx уж сам постарайся ;-) |
Сообщ.
#8
,
|
|
|
Нужно уметь читать справки по Windows API. Там ясно написано:
Цитата lpProgressRoutine Specifies the address of a callback function of type LPPROGRESS_ROUTINE that is called each time another portion of the file has been copied. This parameter can be NULL. For more information on the progress callback function, see CopyProgressRoutine. |
Сообщ.
#9
,
|
|
|
Вот нашёл описание этих функций(правда для C++). Как мне соединить всё это . Напишите пример.
BOOL CopyFileEx( LPCTSTR lpExistingFileName, // имя существующего файла LPCTSTR lpNewFileName, // имя нового файла LPPROGRESS_ROUTINE lpProgressRoutine, // функция обратного вызова LPVOID lpData, // параметры обратного вызова LPBOOL pbCancel, // отмененный статус DWORD dwCopyFlags // опции копирования ); DWORD CALLBACK CopyProgressRoutine( LARGE_INTEGER TotalFileSize, // размер файла LARGE_INTEGER TotalBytesTransferred, // переносимые байты LARGE_INTEGER StreamSize, // байты в потоке LARGE_INTEGER StreamBytesTransferred, // переносимые потоком байты DWORD dwStreamNumber, // текущий поток DWORD dwCallbackReason, // причина возврата HANDLE hSourceFile, // дескриптор источ. файла HANDLE hDestinationFile, // дескриптор целевого файла LPVOID lpData // из CopyFileEx ); M Сообщения были разделены в тему "Копирование" |
Сообщ.
#10
,
|
|
|
Хорошо, с копированием разобрался. Как же быть с перемещением и УДАЛЕНИЕМ (тоже с ProgressBar)?
|
Сообщ.
#11
,
|
|
|
Перемешение и удаление требует предварительно составить список файлов, это если удалять не с помощью ShFileOperation. Есть простое правило, все операции по работе с файлами делать с помощью ShFileOperation, за исключением особых случаев. Кодирование простое, а пользователю знаком привычный внешний вид и поведение.
|
Сообщ.
#12
,
|
|
|
Для копирования, преремещения etc, можно использовать бестиповые файлы... И с ProgressBar'ом никаких проблем не будет...
|
Сообщ.
#13
,
|
|
|
Цитата Heretic2 @ Значит не правильно пробовал. Зачем тут рекурсия при коприровании? Рекурсия нудна только чтоб создать список файлов, а копировать можно и в цикле. Цитата Heretic2, в FAQ есть алгоритм перебора всех файлов во всех директориях рекурсивно. Используй его и для каждого выполняй процедуру копирования файла. Я так уже пробовал и у меня прога вылетает, если в папке 2000 или более файлов. |
Сообщ.
#14
,
|
|
|
И в цикле тоже вылетает!!!
|