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

Вниз

Непонятная работа FindFirst / FindNext   Найти похожие ветки 

 
Piter ©   (2006-07-04 18:58) [0]

Алгоритм подсмотрен в справке Delphi:


 FileAttrs := faReadOnly or faSysFile or faVolumeID or faArchive ;
 if FindFirst(<ПУТЬ>, FileAttrs, sr) = 0 then
 repeat
   SizeInt := sr.FindData.nFileSizeHigh shl 32;
   SizeInt := SizeInt + sr.FindData.nFileSizeLow ;
   if ( (sr.Attr and FileAttrs) = sr.Attr) and ( SizeInt > 0 ) then
...


Собственно, проверка условия: (sr.Attr and FileAttrs) = sr.Attr взята из справки.

Вопросы - а зачем нужно это условие проверки? Дело в том, что у пользователей выявлены ситуации, когда это условие НЕ выполняется (хотя файлы подпадают под критерий поиска). Например, бывает такое:

sr.Attr = 8224 = $00002020
FileAttrs = 45 = $0000002D

Вообще странно, если судить по объявлению констант:

{ File attribute constants }

 faReadOnly  = $00000001 platform;
 faHidden    = $00000002 platform;
 faSysFile   = $00000004 platform;
 faVolumeID  = $00000008 platform;
 faDirectory = $00000010;
 faArchive   = $00000020 platform;
 faSymLink   = $00000040 platform;
 faAnyFile   = $0000003F;


Значений выше $3F и быть не должно... А вот нате...


 
guav ©   (2006-07-04 19:15) [1]

см. в msdn по WIN32_FIND_DATA, какие сейчас бывают атрибуты.

из JwaWinNT.pas
 FILE_SHARE_READ                    = $00000001;
 {$EXTERNALSYM FILE_SHARE_READ}
 FILE_SHARE_WRITE                   = $00000002;
 {$EXTERNALSYM FILE_SHARE_WRITE}
 FILE_SHARE_DELETE                  = $00000004;
 {$EXTERNALSYM FILE_SHARE_DELETE}
 FILE_ATTRIBUTE_READONLY            = $00000001;
 {$EXTERNALSYM FILE_ATTRIBUTE_READONLY}
 FILE_ATTRIBUTE_HIDDEN              = $00000002;
 {$EXTERNALSYM FILE_ATTRIBUTE_HIDDEN}
 FILE_ATTRIBUTE_SYSTEM              = $00000004;
 {$EXTERNALSYM FILE_ATTRIBUTE_SYSTEM}
 FILE_ATTRIBUTE_DIRECTORY           = $00000010;
 {$EXTERNALSYM FILE_ATTRIBUTE_DIRECTORY}
 FILE_ATTRIBUTE_ARCHIVE             = $00000020;
 {$EXTERNALSYM FILE_ATTRIBUTE_ARCHIVE}
 FILE_ATTRIBUTE_DEVICE              = $00000040;
 {$EXTERNALSYM FILE_ATTRIBUTE_DEVICE}
 FILE_ATTRIBUTE_NORMAL              = $00000080;
 {$EXTERNALSYM FILE_ATTRIBUTE_NORMAL}
 FILE_ATTRIBUTE_TEMPORARY           = $00000100;
 {$EXTERNALSYM FILE_ATTRIBUTE_TEMPORARY}
 FILE_ATTRIBUTE_SPARSE_FILE         = $00000200;
 {$EXTERNALSYM FILE_ATTRIBUTE_SPARSE_FILE}
 FILE_ATTRIBUTE_REPARSE_POINT       = $00000400;
 {$EXTERNALSYM FILE_ATTRIBUTE_REPARSE_POINT}
 FILE_ATTRIBUTE_COMPRESSED          = $00000800;
 {$EXTERNALSYM FILE_ATTRIBUTE_COMPRESSED}
 FILE_ATTRIBUTE_OFFLINE             = $00001000;
 {$EXTERNALSYM FILE_ATTRIBUTE_OFFLINE}
 FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = $00002000;
 {$EXTERNALSYM FILE_ATTRIBUTE_NOT_CONTENT_INDEXED}
 FILE_ATTRIBUTE_ENCRYPTED           = $00004000;


 
Юрий Зотов ©   (2006-07-04 19:45) [2]

> Piter ©   (04.07.06 18:58)

Это флаг FILE_ATTRIBUTE_NOT_CONTENT_INDEXED ($2000). В SR.Attr он будет установлен, если в свойствах файла (каталога, диска) сброшена птичка "разрешить индексацию".


 
Piter ©   (2006-07-04 20:07) [3]

Ясно, спасибо!

И какие рекомендации по устранению теперь? Получается, что пример в справке по delphi не совсем корректен...

Убирать проверку: "(sr.Attr and FileAttrs) = sr.Attr " ? Но ведь Borland не зря эту проверку написал. Я так, кстати, и не понял - зачем она?

И второй вопрос тогда:
получается значение:

faAnyFile   = $0000003F;

так теперь просто некорректно?


 
Пусик ©   (2006-07-04 21:26) [4]


> Piter ©

if ( (sr.Attr and FileAttrs) = sr.Attr)

Здесь ты сравниваешь на ПОЛНОЕ совпадение.
Но ведь в атрибутах файла могут быть и другие флаги, кроме тех, которые проверяешь? И полного совпадения не будет.


 
Пусик ©   (2006-07-04 21:34) [5]


> > Piter ©if ( (sr.Attr and FileAttrs) = sr.Attr)


Прошу прощения, ошиблась. спать уже пора.
Просто надо так: ( (sr.Attr and FileAttrs) = FileAttrs)


 
Piter ©   (2006-07-04 21:37) [6]

Кажется понял логику работы...

То есть:

FileAttrs := faReadOnly or faSysFile or faVolumeID or faArchive ;
if FindFirst(<ПУТЬ>, FileAttrs, sr) = 0 then


это гарантирует, что у файла будет хотя бы один из 4-ех вышеперечисленных флагов, но не факт, что не будет других...

Блин, логично... Но как-то неочевидно :)

Всем спасибо.


 
Piter ©   (2006-07-04 21:48) [7]

То есть, фактически я не могу в FindFirst задать такое условие, чтобы, например, найти все объекты, исключая директории и скрытые файлы...


 
Пусик ©   (2006-07-04 22:07) [8]


> Piter ©   (04.07.06 21:48) [7]
> То есть, фактически я не могу в FindFirst задать такое условие,
>  чтобы, например, найти все объекты, исключая директории
> и скрытые файлы...


Для такой задачи можно не задавать атрибуты, кроме faAnyFIle, а проверять каждый файл на нужные атрибуты, тем более, что алгоритм поиска в FindFirst/FindNext/FindClose Все равно предполагает полный перебор всех файлов.


 
Игорь Шевченко ©   (2006-07-04 23:41) [9]


> if ( (sr.Attr and FileAttrs) = sr.Attr)


if ( (sr.Attr and FileAttrs) = FileAttrs) ?


 
Германн ©   (2006-07-05 03:19) [10]


> Игорь Шевченко ©   (04.07.06 23:41) [9]
> if ( (sr.Attr and  FileAttrs) = FileAttrs) ?


Пуся уже это предложила в Пусик ©   (04.07.06 21:34) [5]


 
Piter ©   (2006-07-05 12:28) [11]

Пусик ©   (04.07.06 21:34) [5]
Просто надо так: ( (sr.Attr and FileAttrs) = FileAttrs)


не понимаю, а зачем?
Ведь данная строчка будет проверять одновременное наличие всех четырех флагов. А мне не это надо, мне просто нужно искать файлы, который имеют один из вышеперечисленных флагов:

Piter ©   (04.07.06 18:58)
FileAttrs := faReadOnly or faSysFile or faVolumeID or faArchive ;


 
Игорь Шевченко ©   (2006-07-05 12:51) [12]

( (sr.Attr and FileAttrs) = (sr.Attr and faAnyFile)) ?


 
Piter ©   (2006-07-05 14:29) [13]

Игорь Шевченко ©   (05.07.06 12:51) [12]
( (sr.Attr and FileAttrs) = (sr.Attr and faAnyFile)) ?


а смысл? Во-первых, тут не учитывается то, что у меня не обрабатываются скрытые файлы, директории и т.д.
Во-вторых, насколько я понял условие - зачем оно? Ведь в FindFirst передается FileAttrs, и она не отработает, если ни одного из флагов FileAttrs у файла не будет.


 
Игорь Шевченко ©   (2006-07-05 14:35) [14]

Piter ©   (05.07.06 14:29) [13]

Тогда я тебя не понимаю. Тебе надо проанализировать, если ли у файла хоть один атрибут из переданных тобой. Ты можешь посмотреть, как работает FindFirst, список переданных атрибутов обрабатывается в SysUtils.pas в процедуре FindMatchingFile


 
Piter ©   (2006-07-05 14:52) [15]

Та-а-ак... Я опять запутался...

Вот при таком поиске:

FileAttrs := faReadOnly or faSysFile or faVolumeID or faArchive ;
if FindFirst(<ПУТЬ>, FileAttrs, sr) = 0 then


Возможно, что будут найдены объекты с флагом: faDirectory?


 
Игорь Шевченко ©   (2006-07-05 15:17) [16]

Piter ©   (05.07.06 14:52) [15]

const
faSpecial = faHidden or faSysFile or faVolumeID or faDirectory;

begin
 F.ExcludeAttr := not Attr and faSpecial;

делаем преобразование твоих атрибутов:


> not faReadOnly or faSysFile or faVolumeID or faArchive


and


> faHidden or faSysFile or faVolumeID or faDirectory;


получаем в ExcludeAttr комбинацию faDirectory + faHidden.

Файлы с этими атрибутами не будут попадать в результат.


 
Piter ©   (2006-07-05 16:08) [17]

Ладно, с комбинациями пока не важно. Сейчас меня интересует:

Вот при таком поиске:

FileAttrs := faReadOnly or faSysFile or faVolumeID or faArchive ;
if FindFirst(<ПУТЬ>, FileAttrs, sr) = 0 then


Возможно, что будут найдены объекты с флагом: faDirectory?

Судя по всему, не находятся! Так почему же находятся объекты с доп. флагом: FILE_ATTRIBUTE_NOT_CONTENT_INDEXED хоть он и не указан в FileAttrs ?

Игорь Шевченко ©   (05.07.06 15:17) [16]
begin
F.ExcludeAttr := not Attr and faSpecial;


что такое F?


 
PSPF2003 ©   (2006-07-05 16:50) [18]

Вот хотел поинтересоваться. У меня есть программа, которая сканирует выбранную директорию. И если начать просмотр в папке Windows/System32 (файлов и папок в директории более 2000) она глохнет на достаточно длинный промежуток. Есть ли какие-то альтернативы?


 
Eraser ©   (2006-07-05 16:56) [19]

> [17] Piter ©   (05.07.06 16:08)

я вот вообще, для простоты чтения/написания программы и прозрачной логики, всегда указываю FileAttrs = faAnyFile, а уже у найденого файла анализирую sr.Attr на предмет нужных мне атрибутов.


 
Eraser ©   (2006-07-05 16:56) [20]

> [18] PSPF2003 ©   (05.07.06 16:50)

производить поиск в доп. потоке.


 
PSPF2003 ©   (2006-07-05 16:59) [21]

В потоке? Хм… Надо попробовать.


 
Игорь Шевченко ©   (2006-07-05 17:09) [22]


> что такое F?


[14]



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

Текущий архив: 2006.08.20;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.076 c
1-1152025091
Piter
2006-07-04 18:58
2006.08.20
Непонятная работа FindFirst / FindNext


2-1154035695
Khabibulin
2006-07-28 01:28
2006.08.20
Физический размер ПИКСЕЛЯ


2-1154495419
SerJaNT
2006-08-02 09:10
2006.08.20
Эффект 3D - кнопки


4-1146479765
Kukuruza
2006-05-01 14:36
2006.08.20
Registry и DWORD


15-1153837535
Parus
2006-07-25 18:25
2006.08.20
Сайт