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

Вниз

Посмотрите на код и оцените с точки зрения оптимальности и вообще   Найти похожие ветки 

 
iNew ©   (2003-03-27 07:46) [0]

//Копирование вместе с поддерикториями.
procedure TMailForm.CopyWithSubDir(SourceDir,DestDir:string);
var lpFD : WIN32_FIND_DATA;
hd : integer;
DirTo : String;
begin
hd:=FindFirstFile(PChar(SourceDir+"\*.*"),lpFd);
FindNextFile(hd,lpFD);
while FindNextFile(hd,lpFD) do
begin
if lpFD.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY=0 then
begin
CopyFile(SourceDir+"\"+lpFd.cFileName,DestDir+"\"+lpFD.cFileName);
end;
if lpFD.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY<>0 then
begin
DirTo:=DestDir+"\"+lpFD.cFileName;
if not DirectoryExists(DirTo) then
CreateDir(DirTo);
CopyWithSubDir(SourceDir+"\"+lpFD.cFileName,DirTo);
end;
end;
Windows.FindClose(hd);
end;


 
Юрий Зотов ©   (2003-03-27 08:41) [1]

1. Код не скомпилируется. А было бы неплохо хотя бы попробовать, прежде чем выкладывать его сюда.
2. При любом исключении FindClose вызвана не будет, прервется вся рекурсивная цепочка и произойдет утечка ресурсов (величина которой будет зависеть от достигнутой глубины рекурсии и может оказаться совсем не маленькой).
3. Перед вызовом процедур с заранее неизвестной глубиной рекурсии неплохо установить максимальный размер стека, дабы снизить шанс его переполнения.
4. Первый найденный каталог/файл не скопируется.
5. SourceDir и DestDir могут содержать в себе конечный "\".
6. Нет проверок текущего и родительского каталога ("." и "..").
7. if lpFD.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY <> 0
Эта проверка лишняя, существует else.


 
iNew ©   (2003-03-27 08:51) [2]

1. Код скомпилировался (почему не скомпилируется).
2. Как исправить?
3. Как это сделать?
4. Проверил копируются все файлы и каталоги.
5. SourceDir и DestDir содержать "\" не будут.
6. Не понял.
7. Исправил.


 
Anatoly Podgoretsky ©   (2003-03-27 08:52) [3]

В дополнение.
НЕ стоит писать то, что реализовано функция ОС, SHFileOperation, если на то нет важных оснований, это надо принять за правило.

1. Не скомпилируется из за подобных вещей lpFD.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY=0
Но это мелочи, просто синтактическая ошибка, а концептуальные Зотов уже указал, на мой взляд из них самая существенная, это отсутствие обработки критических ситуаций пункты 2, 3, 5 и 6.


 
Anatoly Podgoretsky ©   (2003-03-27 09:02) [4]

В дополнение к критичным ошибка, следует указать еще следующее FindClose должен вызываться только в случае правильно отработавшего вызова FindFirstFile, подобная ошибка существовала в Дельфи 3, в функции FindClose

Еще одна ошибка, ты проверяешь наличие каталога только во второй части и создаешь его, но точно также каталог может не существовать и в первой части, при копировании файла, создание каталога надо вывести на более ранный уровень.


 
iNew ©   (2003-03-27 09:12) [5]

>Anatoly Podgoretsky
Что-то я не понял.
Нашли файл, скопировали.
Нашли директорию, создали. Затем из найденой директории копируем
в созданную и т.д.


 
Юрий Зотов ©   (2003-03-27 09:18) [6]

> iNew © (27.03.03 08:51)

1. Например, из-за CopyFile (string вместо PChar).
2. try-finally.
3. Директива $M.
4. Связка перед циклом
hd:=FindFirstFile(PChar(SourceDir+"\*.*"),lpFd);
FindNextFile(hd,lpFD);

пропускает первый найденный файл/каталог.
5. Откуда такая уверенность? А если будут? Разве что-то мешает?
6. Пройдите отладчиком и просмотрите значения lpFD.cFileName. Сразу поймете.

В дополнение:
8. Нет никакой диагностики ошибок.


 
Raptor ©   (2003-03-27 09:56) [7]

Для рекурсивного перебора я всегда использую такую процедуру (мной написаную)

Type
ParseDirProc=Procedure (FileName:String);

Procedure ParseDirectory(Dir,Mask:String;f:ParseDirProc;Sub:Boolean);
Var SRec:TSearchRec;
Res:Integer;
Begin
If Not Sub Then
Begin OutFileName(Dir,Mask,f);Exit; End;
Res:=FindFirst(Dir+"\*.*",faDirectory,SRec);
While Res=0 Do
Begin
If (SRec.Name<>".") And (SRec.Name<>"..") Then ParseDirectory(Dir+"\"+SRec.FindData.cFileName,Mask,f,Sub);
Res:=FindNext(SRec);
End;
OutFileName(Dir,Mask,f);
End;


 
iNew ©   (2003-03-27 10:17) [8]

1. Забыл сказать CopyFile это моя процедура
2. Где нужно вставить?
3. Где нужно вставить?
4. Сделал так: hd:=FindFirstFile(PChar(SourceDir+"\*.*"),lpFd);
ListBox1.items.append(lpFd.cFileName);
FindNextFile(hd,lpFD);
ListBox1.items.append(lpFd.cFileName);
в результате в ListBoxe следующее: .
..
5. Уверенность есть
6. Это пункт я так и не могу догнать. Проверял, копируются все
файлы и дериктории начиная с первого SourceDir и ниже

8. Какая диагностика кроме try-finally?


 
iNew ©   (2003-03-27 10:19) [9]

к предыдущему
В результате в ListBoxe следующее: . и ..


 
Raptor ©   (2003-03-27 10:29) [10]

Да, забыл

Procedure OutFileName(Dir,Mask:String;f:ParseDirProc);
Var SRec:TSearchRec;
Res:Integer;
Begin
Res:=FindFirst(Dir+"\"+Mask,$01 and $02 and $04 and $20,SRec);
While Res=0 Do
Begin
F(Dir+"\"+SRec.FindData.cFileName);
Res:=FindNext(SRec);
End;
End;

В ф-ции F делаешь с полученым именем файла все что хочешь, в том числе и копировать его можешь.



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

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

Наверх




Память: 0.5 MB
Время: 0.02 c
14-83738
Sour
2003-05-07 11:12
2003.05.26
Метод Рунге-Кутта


3-83395
anpv
2003-05-06 14:57
2003.05.26
UPDATE BLOB = INSERT


1-83528
cult
2003-05-13 11:49
2003.05.26
Импорт ActiveX-компонента


3-83422
ArtemB
2003-05-07 09:26
2003.05.26
Фильтр на базу


8-83612
bil
2003-02-09 13:22
2003.05.26
Как убрать мерцание при выводе на канвас.