Текущий архив: 2004.03.28;
Скачать: CL | DM;
Вниз
И все же. По поводу граблей при поиске файлов. Найти похожие ветки
← →
panov © (2004-03-04 16:12) [0]Изначальная ссылка.
http://delphimaster.net/view/1-1078326766/
Найдите ошибку в следующем коде:
Задача найти все файлы в корневом каталоге диска C.function FindMyFile(const aPath: String;var aListFile: TStringList): Integer;
var
SR: TSearchRec;
FileAttrs: Integer;
tPath: String;
begin
tPath := IncludeTrailingBackSlash(aPath);
FileAttrs := faAnyFile-faDirectory-faVolumeId;
if FindFirst(tPath+"*.*",FileAttrs,SR)=0 then
begin
try
repeat
if (SR.Attr and FileAttrs)=SR.Attr then aListFile.Add(tPath+SR.Name);
until FindNext(SR)<>0;
finally
Sysutils.FindClose(SR);
end;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
tListFiles: TStringList;
begin
tListFiles := TStringList.Create;
try
FindMyFile("c:\",tListFiles);
tListFiles.SaveToFile("c:\ListFiles.txt");
finally
tListFiles.Free;
end;
end;
← →
pasha_golub © (2004-03-04 16:14) [1]Уточняющуй вопрос:
А почему кругом вызовы простые, а этот:
Sysutils.FindClose(SR);
уточняющий?
← →
Verg © (2004-03-04 16:16) [2]
> (SR.Attr and FileAttrs)=FileAttrs
← →
Anatoly Podgoretsky © (2004-03-04 16:17) [3](SR.Attr and FileAttrs)=SR.Attr
← →
MBo © (2004-03-04 16:17) [4]if плохой
← →
panov © (2004-03-04 16:17) [5]>pasha_golub © (04.03.04 16:14) [1]
FindClose есть еще в модуле system и windows.
← →
keymaster © (2004-03-04 16:18) [6]А где оно падает?
И как при этом ругается?
← →
pasha_golub © (2004-03-04 16:18) [7]2panov ©
Вы говорили, что ошибки две. Или я ошибаюсь?
← →
panov © (2004-03-04 16:18) [8]>Verg © (04.03.04 16:16) [2]
>Anatoly Podgoretsky © (04.03.04 16:17) [3]
>MBo © (04.03.04 16:17) [4]
А кратенькое обоснование?-)
← →
panov © (2004-03-04 16:19) [9]>pasha_golub © (04.03.04 16:18)
Нет, здесь одна ошибка...
← →
Anatoly Podgoretsky © (2004-03-04 16:20) [10]Verg © (04.03.04 16:16) [2]
Точно такая же, будут найдены не все файлы, а только те у которых аттрибуты точно совпадают
Достаточный уровень такой
try
repeat
aListFile.Add(tPath+SR.Name);
until FindNext(SR)<>0;
finally
Sysutils.FindClose(SR);
end;
← →
pasha_golub © (2004-03-04 16:20) [11]panov © (04.03.04 16:17) [5]
Аналогично, FindFirst & FindNext в тех же модулях имеются.
← →
Verg © (2004-03-04 16:21) [12]Тебе нужно множества, у которых в подмножестве FileAttr, а не мнеожества равные FileAttr
Наверно так?
А что?
Просто спешу...
← →
keymaster © (2004-03-04 16:21) [13]У меня всё замечательно работает...
← →
Anatoly Podgoretsky © (2004-03-04 16:21) [14]panov © (04.03.04 16:18) [8]
Представим себе файл со сброшеннымт аттрибутом, ну скажем ReadOnly он уже в выборку не попадет.
← →
MBo © (2004-03-04 16:21) [15]>А кратенькое обоснование?-)
Набор флагов в найденном SR.Attr может отличаться от FileAttrs, например, не будет Hidden и т.д.
← →
panov © (2004-03-04 16:22) [16]>keymaster © (04.03.04 16:18) [6]
А где оно падает?
И как при этом ругается?
Не ругается и не падает-)
Просто результат будет не тот, который ожидался-)
← →
panov © (2004-03-04 16:23) [17]MBo © (04.03.04 16:21) [15]
Набор флагов в найденном SR.Attr может отличаться от FileAttrs, например, не будет Hidden и т.д.
Ообрати внимание, что в правой части сравнения SR.ATTR.
← →
panov © (2004-03-04 16:25) [18]>MBo © (04.03.04 16:21) [15]
Например, SR.Attr=00000001, FileAttrs, допустим равен 00000011.
Условие выполняется.
← →
Anatoly Podgoretsky © (2004-03-04 16:25) [19]в более грубой форме это выражено в Verg © (04.03.04 16:16) [2]
← →
Anatoly Podgoretsky © (2004-03-04 16:27) [20]panov © (04.03.04 16:25) [18]
Ну AnyFiles не перекрывает все возможные аттрибуты, на платформе НТ есть еще ряд.
← →
Юрий Зотов © (2004-03-04 16:27) [21]Помимо уже указанных, здесь еще две ужаснейших ошибки.
1. FileAttrs - не константа.
2. Лишние begin-end.
Конечно, с такими страшными ошибками работать никак не сможет.
:о)
← →
pasha_golub © (2004-03-04 16:29) [22]>2. Лишние begin-end.
Вот именно в таком случае не будет. После end точка стоит. :-)
← →
panov © (2004-03-04 16:38) [23]>Anatoly Podgoretsky © (04.03.04 16:27) [20]
Совершенно верно.-)
Поэхтому такой метод в принципе неверен, и пример из Help в чистом виде использовать нельзя.
>Юрий Зотов © (04.03.04 16:27) [21]
Помимо уже указанных, здесь еще две ужаснейших ошибки.
1. FileAttrs - не константа.
2. Лишние begin-end.
Разве?-)
← →
Anatoly Podgoretsky © (2004-03-04 16:42) [24]panov © (04.03.04 16:38) [23]
Пункт 2. да есть лишнии begin-end. Try/Finally/End с тем же успехом выполняю эту роль.
← →
panov © (2004-03-04 16:44) [25]>Anatoly Podgoretsky © (04.03.04 16:42) [24]
Ну в данном случае это не ошибка... В это блоке могли бы быть и другие операторы.
← →
panov © (2004-03-04 16:47) [26]Видимо, Анатолий Подгорецкий сталкивался с такой особенностью.
faAnyFile = $0000003F;
Но в WinNT и выше появились еще атрибуты. Такие например, как FileCompressed ($00000800)
← →
MBo © (2004-03-04 16:47) [27]>Ну AnyFiles не перекрывает все возможные аттрибуты, на платформе НТ есть еще ряд.
Ах, вон где собака порылась ;)))
← →
Anatoly Podgoretsky © (2004-03-04 16:48) [28]Это не ошибка и без жругих операторов, просто в данном коде лишнее. Зато в коде нед другой неявной ошибки, когда FindClose делают вне зависимости от FindFirst на Д3 это было бы ошибкой, далее они предприняли меры, если FindFirst не прошел, то во внутренею переменную записывается этот факт и FindClose не исполняется, а такой ошибкой часто грешат.
← →
Anatoly Podgoretsky © (2004-03-04 16:51) [29]Например Compressed и другие.
Но мне не нравится само сравнение (SR.Attr and FileAttrs)=SR.Attr в случае когда атррибут каталога не удален, результат получается сразу странный
← →
panov © (2004-03-04 16:51) [30]>Anatoly Podgoretsky © (04.03.04 16:48) [28]
Ну если уж внимательнее посмотреть, то есть еще место, где может быть ошибка, потому код и обернут в try..finally..end - then aListFile.Add(tPath+SR.Name);
← →
Anatoly Podgoretsky © (2004-03-04 16:56) [31]К try..finally..end претензий нет, здесь все правильно.
← →
panov © (2004-03-04 16:59) [32]Ну теперь осталось привести полностью точный код, без особенностей отрабатывающий в любой Windows-системе для поставленной в начале задачи. И еще дать метод решения на будущее-)
← →
Verg © (2004-03-04 16:59) [33]Так, так. Сейчас пороетесь и найдете еще десяток ошибок :))
← →
Anatoly Podgoretsky © (2004-03-04 17:01) [34]panov © (04.03.04 16:59) [32]
faAnyFile = $FFFFFFFF
← →
panov © (2004-03-04 17:39) [35]Ну и решение поставленной задачи. Правда я его модифицировал для поиска всех подкаталогов и файлов, исключая файлы с нужными атрибутами.
В примере будут найдены все файлы, у которых отсутствует атрибут faReadOnly в Program Files и подкаталогах.
function GetFiles(const aPath: String;const aExcludeAttr: Integer;var aListFile: TStringList): Integer;
var
SR: TSearchRec;
tPath: String;
begin
tPath := IncludeTrailingBackSlash(aPath);
if FindFirst(tPath+"*.*",faAnyFile,SR)=0 then
begin
try
repeat
if (SR.Name=".") or (SR.Name="..") then Continue;
if (SR.Attr and faDirectory)<>0 then GetFiles(tPath+SR.Name,aExcludeAttr,aListFile);
if (SR.Attr and aExcludeAttr)<>0 then Continue;
aListFile.Add(tPath+SR.Name);
until FindNext(SR)<>0;
finally
Sysutils.FindClose(SR);
end;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
tListFiles: TStringList;
begin
tListFiles := TStringList.Create;
try
GetFiles("c:\Program Files",faReadOnly,tListFiles);
tListFiles.SaveToFile("c:\ListFiles.txt");
finally
tListFiles.Free;
end;
т.е. метод решения:
Проверять на "ненужные" атрибуты.
Страницы: 1 вся ветка
Текущий архив: 2004.03.28;
Скачать: CL | DM;
Память: 0.53 MB
Время: 0.027 c