Форум: "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