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

Вниз

Непонятная работа 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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.51 MB
Время: 0.045 c
6-1144050156
Kryakozyablik
2006-04-03 11:42
2006.08.20
Авторизация с использованием Indy.


2-1154421420
RomanH
2006-08-01 12:37
2006.08.20
SQL-запрос


6-1143505652
Sergio77
2006-03-28 04:27
2006.08.20
Запрет доступа


2-1154501900
Arsenija
2006-08-02 10:58
2006.08.20
обработка по нажатии ENTER в LabeledEdit


15-1153660036
r@bbit
2006-07-23 17:07
2006.08.20
Алгоритм поиска ближайшего простого числа





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