Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2003.09.04;
Скачать: CL | DM;

Вниз

Вот сделал копирование файлов в отдельном потоке. Оцените.   Найти похожие ветки 

 
iNew ©   (2003-08-21 05:35) [0]

type

TMyThread = class(TThread)
private
SPath : String;
DPath : String;
protected
procedure Execute; override;
procedure MyFindF;
public
constructor Create(SourceDir,DestDir:string);
end;

implementation
uses
Main;

constructor TMyThread.Create(SourceDir,DestDir:string);
begin
inherited Create(True);
FreeOnTerminate := True;
SPath := SourceDir;
DPath := DestDir;
Self.Priority := tpHighest;
Resume;
end;

procedure TMyThread.Execute;
var
FTimeOut: Integer;
EndTime: TDateTime;
begin
FTimeOut := 1;
EndTime := now + (1/24/60)* FTimeOut;
while not Terminated do
begin
Sleep(100);
if Terminated then break;
if now>=EndTime then
begin
Synchronize(MyFindF);
EndTime := now + (1/24/60)* FTimeOut;
end;
end;
end;

function MyCopyFile(FileName, DestName: TFileName):Integer;
var
CopyBuffer: Pointer; { buffer for copying }
BytesCopied: Longint;
Source, Dest: Integer; { handles }
const
ChunkSize: Longint = 8192; { copy in 8K chunks }
begin
GetMem(CopyBuffer, ChunkSize); { allocate the buffer }
try
Source := FileOpen(FileName, fmShareDenyWrite); { open source file }
// if Source < 0 then ShowMessage("Error");
try
Dest := FileCreate(DestName); { create output file; overwrite existing }
// if Dest < 0 then ShowMessage("Error");
try
repeat
BytesCopied := FileRead(Source, CopyBuffer^, ChunkSize); { read chunk }
if BytesCopied > 0 then { if we read anything... }
FileWrite(Dest, CopyBuffer^, BytesCopied); { ...write chunk }
until BytesCopied < ChunkSize; { until we run out of chunks }
finally
FileClose(Dest); { close the destination file }
end;
finally
FileClose(Source); { close the source file }
end;
finally
FreeMem(CopyBuffer, ChunkSize); { free the buffer }
end;
Result:=GetLastError;
end;

procedure TMyThread.MyFindF;
var lpFD : WIN32_FIND_DATA;
hd : integer;
DirTo : String;
str1,str2: String;
MyBool : Boolean;

begin
str1:=".";
str2:="..";
MyBool:=true;
hd:=FindFirstFile(PChar(SPath+"\*.*"),lpFd);
try
while MyBool do
begin
if (lpFD.cFileName <> str1) and (lpFD.cFileName <> str2) then
begin
if lpFD.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY = 0 then
begin
MyCopyFile(SPath+"\"+lpFd.cFileName,DPath+"\"+lpFD.cFileName);
end
else
begin
DirTo:=DPath+"\"+lpFD.cFileName;
if not DirectoryExists(DirTo) then CreateDir(DirTo);
CopyWithSubDir(SPath+"\"+lpFD.cFileName,DirTo);
end;
end;
MyBool:=FindNextFile(hd,lpFD);
end;
finally
Windows.FindClose(hd);
end;
end;
end.

P.S. Только не пинайте сразу. Можно просто словами объяснить :)


 
Evgeny V ©   (2003-08-21 06:25) [1]

Execute - хотел много спросить, но..., не правильно построен алгоритм работы с потоком, в данном случае у тебя нет преимущества работы в другом потоке - Synchronize(MyFindF); ты выполняешь всю работу основную в потоке главного окна, фактически Synchronize шлет SendMessage главному окну, и оно уже выполняет MyFindF, а твой поток в этот момент висит, ждет завершения SendMessage. С таким жк успехом можно было по кнопке делать в основном окне. Не понятно зачем Sleep(100), после него опять проверка на if Terminated then break;, убери Sleep и проверка будет не нужна. С работой с файлами не смотрел внимательно,но сложилось впечатление что и цикл в Execute while тебе вообще не нужен, вроде ты сразу все копируешь, скопировал и выходи из потока. Ошибки есть(алгоритмические), но все поправимо, посмотри хелп по TThread и все будет ок:-))))


 
iNew ©   (2003-08-21 06:49) [2]

> Evgeny V
//не правильно построен алгоритм работы с потоком.

А как надо использовать MyFindF?


 
Zergling ©   (2003-08-21 07:03) [3]

А кто такой CopyWithSubDir

ChunkSize: Longint = 8192;
FileRead(Source, CopyBuffer^, ChunkSize);
А не будет ли ошибки при чтении по 8 кб (выход за конец файла), может лучше ChunkSize: Longint = 1;

Пррисоеденяюсь к Evgeny V ©
Вместо Synchronize(MyFindF) можно слать мессаги или извратиться с глобальными переменными.


 
iNew ©   (2003-08-21 09:12) [4]

> Zergling А кто такой CopyWithSubDir
Ошибочка вышла, там должно быть MyFindF.
> Evgeny V
А если не использовать Synchronize, а содержимое MyFindF
запихать прямо в TMyThread.Execute?


 
iNew ©   (2003-08-21 10:28) [5]

Да точно если Synchronize(MyFindF) то с формой никаких действий
во время копирования произвести нельзя. А вот если сделать
while not Terminated do
begin
Sleep(100);
if Terminated then break;
if now>=EndTime then
begin
MyFindF;
EndTime := now + (1/24/60)* FTimeOut;
end;
end;
end;
то нормально.
Правильно ли так?


 
Evgeny V ©   (2003-08-21 11:52) [6]

Да так можно,а зачем Sleep - не понимаю:-))


 
Игорь Шевченко ©   (2003-08-21 11:56) [7]

SHFileOperation, однако :)))


 
iNew ©   (2003-08-21 12:01) [8]

> Evgeny V а зачем Sleep - не понимаю:-))
http://delphimaster.net/view/1-1061342338/

> Игорь Шевченко SHFileOperation, однако :)))
Я хочу свой ProgressBar :))))


 
Camus ©   (2003-08-21 13:00) [9]

> iNew © (21.08.03 12:01) [8]
> Я хочу свой ProgressBar :))))

А чем "свой" лучше стандартного?


 
panov ©   (2003-08-21 13:03) [10]

Ну написал человек - изучает именно это раздел программирования.

Ему ж совет именно для изучения нужен, доберется и до других методов... позже...


 
panov ©   (2003-08-21 13:14) [11]

Далее возможны 2 пути для взаимодействия для отображения ProgressBar.

1. Создать ProgressBar в основном потоке и уведомлять его об изменении.
2. Создать ProgressBar в отдельном потоке.

В первом случае прочесс копирования будет все-таки притормаживать обновление визуальных объектов приложения.
А использование Application.ProcessMessages замедлит копирование файлов, так как будет довольно частое переключение на выборку сообщений из очереди сообщений.
К тому же поток у тебя создается с приоритетом выше нормального, что тоже повлияет на скорость работы в основном потоке.

Для синхронизации можно использовать либо Synchronize, либо воспользоваться посылкой сообщений для ProgressBar...

Второй метод позволяет избавиться от этих недостатков.



Страницы: 1 вся ветка

Текущий архив: 2003.09.04;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.018 c
1-10797
cancel
2003-08-22 10:12
2003.09.04
Возврат строк из DLL


1-10692
lww
2003-08-20 10:30
2003.09.04
Как написать dll для 1С?


14-10928
peps
2003-08-17 04:38
2003.09.04
компонент


3-10608
Vadim_aka
2003-08-13 16:23
2003.09.04
Как парсировать ТХТ файл в БД InterBase.


1-10805
BuTyc
2003-08-22 07:27
2003.09.04
Системные часы