![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Непонятная работа FindFirst / FindNext
Piter © (2006-07-04 18:58:00)Алгоритм подсмотрен в справке 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 и быть не должно... А вот нате...
Игорь Шевченко (2006-07-05 17:09:00) [1]
> что такое F?
[14]
PSPF2003 (2006-07-05 16:59:00) [2]В потоке? Хм… Надо попробовать.
Eraser (2006-07-05 16:56:00) [3]> [18] PSPF2003 © (05.07.06 16:50)
производить поиск в доп. потоке.
Eraser (2006-07-05 16:56:00) [4]> [17] Piter © (05.07.06 16:08)
я вот вообще, для простоты чтения/написания программы и прозрачной логики, всегда указываю FileAttrs = faAnyFile, а уже у найденого файла анализирую sr.Attr на предмет нужных мне атрибутов.
PSPF2003 (2006-07-05 16:50:00) [5]Вот хотел поинтересоваться. У меня есть программа, которая сканирует выбранную директорию. И если начать просмотр в папке Windows/System32 (файлов и папок в директории более 2000) она глохнет на достаточно длинный промежуток. Есть ли какие-то альтернативы?
Piter (2006-07-05 16:08:00) [6]Ладно, с комбинациями пока не важно. Сейчас меня интересует:
Вот при таком поиске:
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?
Игорь Шевченко (2006-07-05 15:17:00) [7]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 14:52:00) [8]Та-а-ак... Я опять запутался...
Вот при таком поиске:
FileAttrs := faReadOnly or faSysFile or faVolumeID or faArchive ;
if FindFirst(<ПУТЬ>, FileAttrs, sr) = 0 then
Возможно, что будут найдены объекты с флагом: faDirectory?
Игорь Шевченко (2006-07-05 14:35:00) [9]Piter © (05.07.06 14:29) [13]
Тогда я тебя не понимаю. Тебе надо проанализировать, если ли у файла хоть один атрибут из переданных тобой. Ты можешь посмотреть, как работает FindFirst, список переданных атрибутов обрабатывается в SysUtils.pas в процедуре FindMatchingFile
Piter (2006-07-05 14:29:00) [10]Игорь Шевченко © (05.07.06 12:51) [12]
( (sr.Attr and FileAttrs) = (sr.Attr and faAnyFile)) ?
а смысл? Во-первых, тут не учитывается то, что у меня не обрабатываются скрытые файлы, директории и т.д.
Во-вторых, насколько я понял условие - зачем оно? Ведь в FindFirst передается FileAttrs, и она не отработает, если ни одного из флагов FileAttrs у файла не будет.
Игорь Шевченко (2006-07-05 12:51:00) [11]( (sr.Attr and FileAttrs) = (sr.Attr and faAnyFile)) ?
Piter (2006-07-05 12:28:00) [12]Пусик © (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 03:19:00) [13]
> Игорь Шевченко © (04.07.06 23:41) [9]
> if ( (sr.Attr and FileAttrs) = FileAttrs) ?
Пуся уже это предложила в Пусик © (04.07.06 21:34) [5]
Игорь Шевченко (2006-07-04 23:41:00) [14]
> if ( (sr.Attr and FileAttrs) = sr.Attr)
if ( (sr.Attr and FileAttrs) = FileAttrs) ?
Пусик (2006-07-04 22:07:00) [15]
> Piter © (04.07.06 21:48) [7]
> То есть, фактически я не могу в FindFirst задать такое условие,
> чтобы, например, найти все объекты, исключая директории
> и скрытые файлы...
Для такой задачи можно не задавать атрибуты, кроме faAnyFIle, а проверять каждый файл на нужные атрибуты, тем более, что алгоритм поиска в FindFirst/FindNext/FindClose Все равно предполагает полный перебор всех файлов.
Piter (2006-07-04 21:48:00) [16]То есть, фактически я не могу в FindFirst задать такое условие, чтобы, например, найти все объекты, исключая директории и скрытые файлы...
Piter (2006-07-04 21:37:00) [17]Кажется понял логику работы...
То есть:
FileAttrs := faReadOnly or faSysFile or faVolumeID or faArchive ;
if FindFirst(<ПУТЬ>, FileAttrs, sr) = 0 then
это гарантирует, что у файла будет хотя бы один из 4-ех вышеперечисленных флагов, но не факт, что не будет других...
Блин, логично... Но как-то неочевидно :)
Всем спасибо.
Пусик (2006-07-04 21:34:00) [18]
> > Piter ©if ( (sr.Attr and FileAttrs) = sr.Attr)
Прошу прощения, ошиблась. спать уже пора.
Просто надо так: ( (sr.Attr and FileAttrs) = FileAttrs)
Пусик (2006-07-04 21:26:00) [19]
> Piter ©
if ( (sr.Attr and FileAttrs) = sr.Attr)
Здесь ты сравниваешь на ПОЛНОЕ совпадение.
Но ведь в атрибутах файла могут быть и другие флаги, кроме тех, которые проверяешь? И полного совпадения не будет.
Piter (2006-07-04 20:07:00) [20]Ясно, спасибо!
И какие рекомендации по устранению теперь? Получается, что пример в справке по delphi не совсем корректен...
Убирать проверку: "(sr.Attr and FileAttrs) = sr.Attr" ? Но ведь Borland не зря эту проверку написал. Я так, кстати, и не понял - зачем она?
И второй вопрос тогда:
получается значение:
faAnyFile = $0000003F;
так теперь просто некорректно?