Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.03.28;
Скачать: CL | DM;

Вниз

по поводу 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;
Скачать: CL | DM;

Наверх




Память: 0.55 MB
Время: 0.048 c
1-1078572591
clapan
2004-03-06 14:29
2004.03.28
Здравствуйте, подскажите как работать с NMSMTP


1-1078349850
reef
2004-03-04 00:37
2004.03.28
Error creating form "Access violation at XXXXX in vcl50.bpl"


9-1058516958
Sn@ke
2003-07-18 12:29
2004.03.28
RPG - обсуждение.


1-1078910381
Ирайзор
2004-03-10 12:19
2004.03.28
Rich edit , цвета и архивы


14-1077717396
Saturn
2004-02-25 16:56
2004.03.28
Отношение к Библии и к религиям вобще!