Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2003.05.26;
Скачать: [xml.tar.bz2];

Вниз

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

 
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 вся ветка

Форум: "WinAPI";
Текущий архив: 2003.05.26;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.47 MB
Время: 0.01 c
7-83769
_sMile
2003-03-24 11:31
2003.05.26
Как убить приложение?


1-83494
MegaVolt
2003-05-14 11:40
2003.05.26
Как правильно добавлять данные в StringGrid?


4-83796
MUHAMOR
2003-03-24 08:10
2003.05.26
Класс окна EDIT


1-83606
AbrosimovA
2003-05-14 08:52
2003.05.26
Как прочитать файл данных тренда


1-83531
lovres
2003-05-13 11:43
2003.05.26
Вопрос про QReport





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский