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

Вниз

по поводу FindFirst and FindNext...   Найти похожие ветки 

 
mOOx_ ©   (2004-03-03 18:12) [0]

Приветствую.
Проблема в том, что не могу задать Attr так, чтобы возвращались только каталоги. Как не кручусь, возвращается весь набор файлов.
Маску ставлю в *, а Attr в faAnyFile, а затем проверяю, faDirectory есть или нет. Так вот, мой алгоритм с такой логикой работать отказывается. Мне надо, чтоб в результате были только каталоги.
Мастера, я знаю, что Вы добрые и мне поможете. С меня кашаладка :)

PS. могет и пивка :)


 
MBo ©   (2004-03-03 18:18) [1]

В FAQ.
А проверяют наличие флага так:
if (Attr and faDirectory)>0


 
pasha_golub ©   (2004-03-03 18:23) [2]

А на код бы я взглянул. Что это за проверка такая? :-)


 
mOOx_ ©   (2004-03-03 18:27) [3]

Именно так я и проверяю! Проблема вот в чем: есть каталог 111 и есть файл 111.par. Таких каталогов штук 20 (с файлами соответственно) + еще файлов в этой директории полно (около 800). Так вот, если мне нужны только каталоги, то процесс просмотра немного затягивается. Может можно сделать, чтоб сначала искались каталоги, а затем шли файлы? Понятно расписал?


 
mOOx_ ©   (2004-03-03 18:34) [4]

Даже не так (уже весь день копаюсь, сам запутался :) ): идет рекурсивный просмотр папок начиная с корневой. В корне есть папки и пары (т.е. Count(Folders)=Count(.par)). В этих папках как раз и есть 800 файлов. Когда начинается просмотр папки 111 (пример) на предмет наличия в ней папок, то апликуха виснет. Так вот мне надо узнать, есть там папки или нет. Если нет, то и нефиг по такому массиву файлов бегать без надобности. Надо на другую итерацию переходить. Так вот как мне узнать, есть там папки кроме "." и ".."?
Вот теперь вроде яснее (и правельнее).


 
TUser ©   (2004-03-03 18:35) [5]

Вот как пишут в хелпе
   if FindFirst(Edit1.Text, FileAttrs, sr) = 0 then

   begin
     repeat
       if (sr.Attr and FileAttrs) = sr.Attr then
       begin
       RowCount := RowCount + 1;
       Cells[1,RowCount-1] := sr.Name;
       Cells[2,RowCount-1] := IntToStr(sr.Size);
       end;
     until FindNext(sr) <> 0;
     FindClose(sr);
   end;


В твоем случае вместо FileAttrs можно писать faDirectory


 
MBo ©   (2004-03-03 18:36) [6]

FAQ еще раз.


 
mOOx_ ©   (2004-03-03 18:47) [7]

В факах не то совсем.
А вот вызов FindFirst("txt",faDirectory) положительного результата все равно не дает :(


 
savva ©   (2004-03-03 18:48) [8]

сделай FindFirst("*.txt",faDirectory)


 
savva ©   (2004-03-03 18:49) [9]

стоп торможу - директорию ищещь? а чего путь не полный?


 
mOOx_ ©   (2004-03-03 18:51) [10]

да полное там все и правильное, только вот выдает он с таким параметром все равно все файлы


 
mOOx_ ©   (2004-03-03 18:59) [11]

Вообщем все вот как организовано

if Subdir then
 begin
 hFile:=FindFirst(Dir+"\*",faAnyFile,FFile);
 if((hFile=0)and
    ((FFile.Attr and faDirectory) <> 0)and
    (FFile.Name<>".")and
    (FFile.Name<>".."))then
     begin
     if ExitLabel then
       exit;
     CheckFiles(Dir+"\"+FFile.Name,FileName);
     end;
 while(FindNext(FFile)=0)do
   begin
   if(((FFile.Attr and faDirectory) <> 0)and
      (FFile.Name<>".")and
      (FFile.Name<>".."))then
     begin
     if ExitLabel then
       Exit;
     CheckFiles(Dir+"\"+FFile.Name,FileName);
     end;
   end;
 SysUtils.FindClose(FFile);
 end;

Может, конечно, грубовато написано, но уж как умею :)
Так вот. Даже если я указываю faDirectory в FintFirst, то файлы все равно возвращаются. Я как-то не понимаю смысла параметра Attr.


 
viajero   (2004-03-03 19:13) [12]

>Я как-то не понимаю смысла параметра Attr.


function FindFirst(const Path: string; Attr: Integer;
 var F: TSearchRec): Integer;
const
 faSpecial = faHidden or faSysFile or faVolumeID or faDirectory;
begin
 F.ExcludeAttr := not Attr and faSpecial;
 
 // Смысл такой:
 // Если ты не укажешь faDirectory,
 // то директории будут исключены из поиска.
 // А обычные файлы будут найдены в любом случае

 F.FindHandle := FindFirstFile(PChar(Path), F.FindData);
 if F.FindHandle <> INVALID_HANDLE_VALUE then
 begin
   Result := FindMatchingFile(F);
   if Result <> 0 then FindClose(F);
 end else
   Result := GetLastError;
end;


 
Anatoly Podgoretsky ©   (2004-03-03 19:13) [13]

mOOx_ ©   (03.03.04 18:12)  
Нельзя и не пытайся.


 
Юрий Зотов ©   (2004-03-03 19:17) [14]

> mOOx_

Обычные файлы ищутся всегда, отключить их поиск нельзя. Смысл параметра Attr в том, чтобы задать поиск чего-то еще, кроме обычных файлов (если задать Attr=0, то будут искаться только обычные файлы).

Вам нужно первоначально задать faDirectory, а потом проверять ручками, с помощью if и and. И рассмотрите вот такую структуру кода, она проще, короче и надежнее:

procedure ScanDir(Dir: string);
var
 SR: TSearchRec;
begin
 Dir := IncludeTrailingBackslash(Dir);
 if FindFirst(Dir + "*.*", faDirectrory, SR) = 0 then
 try
   repeat
     if (SR.Attr = faDirectory)
        and (SR.Name <> ".") and (SR.Name <> "..") then
     begin
       ... // что-то делаем
       ScanDir(Dir + SR.Name)
     end
   until FindNext(SR) <> 0
 finally
   FindClose(SR)
 end
end;


 
mOOx_ ©   (2004-03-03 19:18) [15]

Спасибо большое за ответы. Больше не пытаюсь.


 
Юрий Зотов ©   (2004-03-03 19:19) [16]

Сорри, вот это неправильно:
if (SR.Attr = faDirectory)

Конечно, надо так:
if (SR.Attr and faDirectory <> 0)


 
mOOx_ ©   (2004-03-03 19:24) [17]

да, так на-а-а-амного красивше. Спасибо.


 
viajero   (2004-03-03 19:45) [18]

Я лично пользуюсь простенькой обёрткой над FindFile/Next/Close:


unit FileIt;

interface

uses
 SysUtils;

type
 PSearchRec = ^TSearchRec;

 IFindFileIterator = interface
 ["{FC595960-347D-11D8-9F00-0050BAF21D9F}"]
   function SearchRec: PSearchRec;
   function Done: Boolean;
   procedure Next;
 end;

function CreateFindFileIterator(const Path: string; Attr: Integer): IFindFileIterator;

{
Example:

 // На мой взгляд, выглядит немного приятнее

 with CreateFindFileIterator("c:\windows\*.*", faDirectory) do
   while not Done do
   begin
     if (SearchRec^.Name <> ".")and
        (SearchRec^.Name <> "..")and
        (SearchRec^.Attr and faDirectory <> 0) then
           ListBox.Items.Add(SearchRec^.Name);
     Next;
   end;  
}

implementation

type
 TFindFileIterator = class(TInterfacedObject, IFindFileIterator)
 private
   FSearchRec: TSearchRec;
   FDone: Boolean;
 public
   constructor Create(const Path: string; Attr: Integer);
   destructor Destroy; override;

   function SearchRec: PSearchRec;
   function Done: Boolean;
   procedure Next;
 end;

function CreateFindFileIterator(const Path: string; Attr: Integer): IFindFileIterator;
begin
 Result := TFindFileIterator.Create(Path, Attr);
end;

{------------------------- TFindFileIterator ----------------------------------}

constructor TFindFileIterator.Create(const Path: string; Attr: Integer);
begin
 FDone := FindFirst(Path, Attr, FSearchRec) <> 0;
end;

destructor TFindFileIterator.Destroy;
begin
 FindClose(FSearchRec);
 inherited;
end;

procedure TFindFileIterator.Next;
begin
 FDone := FindNext(FSearchRec) <> 0;
end;

function TFindFileIterator.Done: Boolean;
begin
 Result := FDone;
end;

function TFindFileIterator.SearchRec: PSearchRec;
begin
 Result := @FSearchRec;
end;

end.


 
icWasya ©   (2004-03-04 10:05) [19]

вся фишка в том, что используется
hFile:=FindFirst(Dir+"\*",faAnyFile,FFile);
вместо
hFile:=FindFirst(Dir+"\*.*",faAnyFile,FFile);


 
KADAN ©   (2004-03-04 10:21) [20]

TDirectoryListbox.ReadDirectoryNames (вкладка Win 3.1)


 
YuRock ©   (2004-03-04 10:45) [21]

Сравнивать надо (корректно) так:


if (SR.Attr and faDirectory) = faDirectory then
 ShowMessage("Да, это директория!");


 
Юрий Зотов ©   (2004-03-04 12:50) [22]

> YuRock ©   (04.03.04 10:45) [21]

С учетом того, что faDirectory есть целая степень двойки, не кажется ли Вам, что
if SR.Attr and faDirectory = faDirectory
и
if SR.Attr and faDirectory <> 0
это одно и тоже?

За исключением того, что второе работает чуть-чуть быстрее...


 
YuRock ©   (2004-03-04 13:01) [23]

> Юрий Зотов ©   (04.03.04 12:50) [22]

В данном случае разницы, конечно, нет, но красивее всегда писать в общем стиле, а то иногда по-запарке можно будет написать <> 0, а затем искать ошибку.


 
MBo ©   (2004-03-04 13:38) [24]

Чудная ошибка, встреченная как-то в чате:
Почему не работает
 Style:=GetWindowLong...
 if (Style and SBS_HORZ)<>0 then (скроллбар горизонтальный)
   

(Причина: SBS_HORZ = 0;)


 
YuRock ©   (2004-03-04 13:48) [25]

Во-во!


 
MBo ©   (2004-03-04 13:55) [26]

>YuRock ©   (04.03.04 13:48) [25]
Угу, но все же faDirectory - "честный" флаг, и с ним сталкивался каждый, поэтому, полагаю, здесь вполне уместно и с нулем сравнить.


 
panov ©   (2004-03-04 14:47) [27]

Для более тонкого понимания:
В Delphi Heplp приводится пример кода для FindFirst:


if FindFirst(Edit1.Text, FileAttrs, sr) = 0 then

   begin
     repeat
       if (sr.Attr and FileAttrs) = sr.Attr then
       begin
       RowCount := RowCount + 1;
       Cells[1,RowCount-1] := sr.Name;
       Cells[2,RowCount-1] := IntToStr(sr.Size);
       end;
     until FindNext(sr) <> 0;
     FindClose(sr);
   end;


Где ошибка в этом коде, кто ответит?


 
Юрий Зотов ©   (2004-03-04 14:50) [28]

> panov ©   (04.03.04 14:47) [27]

Здесь даже не одна, а две ошибки.


 
panov ©   (2004-03-04 15:09) [29]

>Юрий Зотов ©   (04.03.04 14:50) [28]

Ошибки, не каксающиеся сути вопроса о поиске файлов, рассматривать не будем-)


 
Юрий Зотов ©   (2004-03-04 15:10) [30]

> panov ©   (04.03.04 15:09) [29]

Они обе относятся.


 
Skyle ©   (2004-03-05 06:34) [31]

Я вижу только одну ошибку.
Здесь
if (sr.Attr and FileAttrs) = sr.Attr then

а вторую как-то не очень..

И ещё вопрос до кучи : в хелпе каких дельфей такой example приведён? В 5-х немного другой...


 
Kor@l ©   (2004-03-05 09:04) [32]

Незнай как кто ищет а я обычно ищю так
findFirst("*..",afanyfile,sr)
и ставлю условие такое
if (sr.name=".") or (sr.name="..") then {не чего не делю}
else
{а теперь идут имена дерикторий}
вроде сколько не делал всё время работало.


 
Anatoly Podgoretsky ©   (2004-03-05 09:11) [33]

Kor@l ©   (05.03.04 09:04) [32]
Работоспособность {а теперь идут имена дерикторий} исключена.



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

Форум: "Основная";
Текущий архив: 2004.03.28;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.54 MB
Время: 0.033 c
14-1078214320
Соловьев
2004-03-02 10:58
2004.03.28
Мир Интербейз 2-е изд.


9-1062240307
TButton
2003-08-30 14:45
2004.03.28
doCollision


7-1072548423
Morfey
2003-12-27 21:07
2004.03.28
dll


14-1078153488
Я
2004-03-01 18:04
2004.03.28
Кто такие "мастера Делфи"?


7-1072321515
Gigant
2003-12-25 06:05
2004.03.28
Скрытие процесса в ХР 2000





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский