Консультация № 29825
19.11.2005, 20:31
0.00 руб.
0 4 3
Здравствуйте уважаемые эксперты. Суть вопроса: при задании файлового атрибута faDirectory в функции FindFirst должны быть найдены все подкаталоги (или я не прав?), но почему - то выявляются не только подкаталоги но и все др. файлы лежащие в заданной папке (за исключением скрытых), т.е. получается что faDirectory равносилен faAnyFile и чтобы определить подкаталог ли найден все равно придется использовать конструкцию {if (SearchRec.Attr and faDirectory) = SearchRec.Attr} ?

Приложение:
procedure TForm1.Button3Click(Sender: TObject);var sr2 : TSearchRec;begin Memo2.Clear; if FindFirst(‘D:\*‘,faDirectory,sr2) = 0 then begin repeat Memo2.Lines.Add(sr2.Name) until FindNext(sr2) <> 0; end;end;

Обсуждение

Неизвестный
19.11.2005, 20:40
общий
это ответ
Здравствуйте, Teapot!

В приложении код предложенный Ксавье Пачеко
Я делал по нему и все работает

Приложение:
{Copyright © 1999 by Delphi 5 Developer‘s Guide - Xavier Pacheco and Steve Teixeira}unit MainFrm;interfaceuses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, FileCtrl, Grids, Outline, DirOutln;type TMainForm = class(TForm) dcbDrives: TDriveComboBox; edtFileMask: TEdit; lblFileMask: TLabel; btnSearchForFiles: TButton; lbFiles: TListBox; dolDirectories: TDirectoryOutline; SvDialog: TSaveDialog; procedure btnSearchForFilesClick(Sender: TObject); procedure dcbDrivesChange(Sender: TObject); private FFileName: String; function GetDirectoryName(Dir: String): String; procedure FindFiles(APath: String); end;var MainForm: TMainForm; rpFileName : String; flReprt : TextFile; rpStrng1,rpStrng2 : String;implementation{$R *.DFM}function TMainForm.GetDirectoryName(Dir: String): String;{ This function formats the directory name so that it is a valid directory containing the back-slash (\) as the last character. }begin if Dir[Length(Dir)]<> ‘\‘ then Result := Dir+‘\‘ else Result := Dir;end;procedure TMainForm.FindFiles(APath: String);{ This is a procedure which is called recursively so that it finds the file with a specified mask through the current directory and its sub-directories. }var FSearchRec, DSearchRec: TSearchRec; FindResult: integer; function IsDirNotation(ADirName: String): Boolean; begin Result := (ADirName = ‘.‘) or (ADirName = ‘..‘); {} end;begin APath := GetDirectoryName(APath); // Obtain a valid directory name { Find the first occurrence of the specified file name } FindResult := FindFirst(APath+FFileName,faAnyFile+faHidden+faSysFile+faReadOnly,FSearchRec); try { Continue to search for the files according to the specified mask. If found, add the files and their paths to the listbox.} while FindResult = 0 do begin lbFiles.Items.Add(LowerCase(APath+FSearchRec.Name)); Writeln(flReprt,APath+‘ <> ‘+FSearchRec.Name); FindResult := FindNext(FSearchRec); end; { Now search the sub-directories of this current directory. Do this by using FindFirst to loop through each subdirectory, then call FindFiles (this function) again. This recursive process will continue until all sub-directories have been searched. } FindResult := FindFirst(APath+‘*.*‘, faDirectory, DSearchRec); while FindResult = 0 do begin if ((DSearchRec.Attr and faDirectory) = faDirectory) and not IsDirNotation(DSearchRec.Name) then FindFiles(APath+DSearchRec.Name); // Recursion here FindResult := FindNext(DSearchRec); end; finally FindClose(FSearchRec); end;end;procedure TMainForm.btnSearchForFilesClick(Sender: TObject);{ This method starts the searching process. It first changes the cursor to an hourglass since the process may take awhile. It then clears the listbox and calls the FindFiles() function which will be called recursively to search through sub-directories }begin if SvDialog.Execute then rpFileName := SvDialog.FileName; AssignFile(flReprt,rpFileName); ReWrite(flReprt); Screen.Cursor := crHourGlass; try lbFiles.Items.Clear; FFileName := edtFileMask.Text; FindFiles(dolDirectories.Directory); CloseFile(flReprt); finally Screen.Cursor := crDefault; end;end;procedure TMainForm.dcbDrivesChange(Sender: TObject);begin dolDirectories.Drive := dcbDrives.Drive;end;end.
Неизвестный
19.11.2005, 20:58
общий
2 Архангельский Андрей Германович :вы немного меня не поняли. Я хотел сказать зачем в принципе нужен этот атрибут если он не работает?Взято из вашего приложения :FindResult := FindFirst(APath+‘*.*‘, faDirectory, DSearchRec);//здесь явным образом указывается что искать нужно подкаталоги...if ((DSearchRec.Attr and faDirectory) = faDirectory) //а здесь проверяется является ли найденый файл подкаталогомОтсюда следует что поиск можно задавать и атрибутом faAnyFile - результат все равно не изменится
Неизвестный
19.11.2005, 22:41
общий
это ответ
Здравствуйте, Teapot!

Надо добавить
...
f sr2.Attr=FaDirectory then
Memo2.Lines.Add(sr2.Name)
until FindNext(sr2)>0
...
Полный код смотрите в приложении.
Удачи в кодинге!


Приложение:
procedure TForm1.Button1Click(Sender: TObject);var sr2 : TSearchRec;begin Memo2.Clear;if FindFirst(‘D:\*‘,faDirectory,sr2) = 0 thenbegin repeatif sr2.Attr=FaDirectory thenMemo2.Lines.Add(sr2.Name)until FindNext(sr2)>0end;end;
давно
Мастер-Эксперт
425
4118
20.11.2005, 08:32
общий
это ответ
Здравствуйте, Teapot!
Да, как ни странно, но так оно и есть. :)
Мне, если честно, тоже непонятно, зачем так делать. Но, тем не менее, если посмотреть в хелпе на описание этого параметра, то там можно найти такую строку:
"The Attr parameter specifies the special files to include in addition to all normal files"
или по-русски говоря:
"Параметр Attr ДОБАВЛЯЕТ заданый Вами аттрибут к аттрибуту ‘нормальный файл‘" (т.е. не системный и не скрытый).
Можете для эксперимента вместо faDirectory поставить 0 ( т.е. без дополнительных аттрибутов) и тогда в списке Вы увидите те самые "нормальные файлы". :)
Об авторе:
Я только в одном глубоко убеждён - не надо иметь убеждений! :)
Форма ответа