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

Вниз

FindFirst-FindNext   Найти похожие ветки 

 
Sandman25 ©   (2003-06-10 16:44) [40]

По-моему, единственное объяснение - не выполняется условие if.

Constant Value Description
faReadOnly $00000001 Read-only files
faHidden $00000002 Hidden files
faSysFile $00000004 System files
faVolumeID $00000008 Volume ID files
faDirectory $00000010 Directory files
faArchive $00000020 Archive files
faAnyFile $0000003F Any file

То есть в NTFS у найденного файла установлены не только младшие 6 бит установлены, но еще установлены какие-то старшие биты. И естественно при проверке $010000xx and $3f мы получаем $000000xx, что не равно исходному $010000xx.
Уберите проверку - она все равно не нужна.


 
Игорь Шевченко ©   (2003-06-10 16:57) [41]

Sandman25 © (10.06.03 16:44)

Единственное объяснение даст выполнение под отладчиком и просмотр значений непосредственно при выполнении проверки. Иначе это гадание на кофейной гуще - а оно нам надо ? :))


 
sniknik ©   (2003-06-10 17:12) [42]

Sandman25 © (10.06.03 16:44)
выполняется. $010000xx and $3f = $000000xx и сравнивается с $000000xx

т.к. являюсь счастливым обладателем диска с разделами разбитыми и под FAT32 и под NTFS решил проверить
собрал весь код из приведенных, частей

procedure TForm1.Button1Click(Sender: TObject);
var sss: string;
sr: TSearchRec;
FileAttrs: Integer;
begin
FileAttrs:= faAnyFile;
sss:= ExtractFileDir(Application.ExeName)+"\*.pas";
if findfirst(sss,FileAttrs, sr) = 0 then
repeat
if ((sr.Attr and FileAttrs) = sr.Attr) then ComboBox1.Items.Add(sr.Name);
until FindNext(sr) <> 0;
FindClose(sr);
end;

могу заверить, в FAT32 и NTFS работает одинаково. система W2k


 
Anatoly Podgoretsky ©   (2003-06-10 17:46) [43]

Anatoly P (10.06.03 13:44)
Доходит, но не всегда, а в очень редких случаяз, только тогда когда sr.Attr = FileAttr
Налицо резкое непонимание работы оператора AND и аттрибутов файла.


 
Anatoly Podgoretsky ©   (2003-06-10 17:51) [44]

Знакомый код, вроде бы был опубликован в каком то Чаво и теперб многие переносяю этот абсурд в свои программы, абсолютно не думая головой, а что же они делают

if ((sr.Attr and FileAttrs) = sr.Attr) then
ComboBox1.Items.Add(sr.Name);


 
Sandman25 ©   (2003-06-10 17:54) [45]

Anatoly Podgoretsky © (10.06.03 17:46)

Нет. Мы сравниваем $xx and $3F с $xx - получается true для любого $xx <= $3F.


 
Sandman25 ©   (2003-06-10 18:01) [46]

Другое дело, что FindFirst/Next и так нам возвращает файл с указанными атрибутами, даже если FileAttr не равно faAnyFile. Зачем еще раз на них проверять, контролируя Windows?


 
Юрий Федоров ©   (2003-06-10 18:41) [47]

Anatoly Podgoretsky © (10.06.03 17:51)
Это не Чаво, это Help по delphi :-)


 
Игорь Шевченко ©   (2003-06-10 18:51) [48]

Юрий Федоров © (10.06.03 18:41)

Точно! :) Осталось выяснить у автора вопроса, что же все-таки отладчик показывает :)))


 
Юрий Федоров ©   (2003-06-10 19:02) [49]

>>Игорь Шевченко © (10.06.03 18:51)
Думаю, это то самое мистическое и тайное знание, которого нам не суждено постичь :-)


 
Anatoly P   (2003-06-10 19:37) [50]

Я бы ответил, но на тех компах нет Delphi. А на домашнем как у всех уважаемых мастеров - нет проблем. Ну вот появился Anatoly Podgoretsky , появляется надежда.


 
sniknik ©   (2003-06-10 19:54) [51]

на моем примере см. выше отладчик кажет (при сравнении)
sr.Attr=32 FileAttrs=63
итого
((32 and 63) = 32) = True

то же самое в столбик
0100000 - 32
0111111 - 63
and
0100000 - 32
=
0100000 - 32
yes!

Anatoly P (10.06.03 19:37)
> Я бы ответил, но на тех компах нет Delphi.
а ты добавь мемо на форму и делай в него лог интересующих переменных, с маркерами где произошло.


 
Anatoly P   (2003-06-10 19:55) [52]

Завтра проверю. Спасибо


 
Anatoly Podgoretsky ©   (2003-06-10 20:00) [53]

Sandman25 © (10.06.03 17:54)
Нет. Мы сравниваем $xx and $3F с $xx - получается true для любого $xx <= $3F.

Нет, мы сравниваем sr.Attr and что то c sr.Attr, а надо бы sr.Attr and что то c что то, в этом и есть ошибка или точнее абсурд, если бы нас интересовали биты за пределами $3F то и надо бы было их проверять.
Я так понимаю, что эти биты как раз не интересуют. А этот код я уже не раз видел. В хелпе действительно такой пример и что они этим хотели сказать не понятно, наверно пытались запутать.


 
han_malign ©   (2003-06-10 20:12) [54]

есть еще атрибуты
FILE_ATTRIBUTE_NORMAL = $00000080;
FILE_ATTRIBUTE_TEMPORARY = $00000100;
FILE_ATTRIBUTE_COMPRESSED = $00000800;

>но на тех компах нет Delphi
- логи - великая вешь, моя текущая задача, в отладке, за час до 5Mb логов пишет, причем режим отладки включается/выключается на лету...


 
nikkie ©   (2003-06-10 20:21) [55]

многие здесь почудили...

>Anatoly Podgoretsky
>Нет, мы сравниваем sr.Attr and что то c sr.Attr, а надо бы sr.Attr and что то c что то, в этом и есть ошибка или точнее абсурд

это как раз сравнение (sr.Attr and что то c что то) будет абсурдом. поскольку это что-то - faAnyFile.


 
Anatoly Podgoretsky ©   (2003-06-10 20:30) [56]

Нет проблема не с левой частью, а с правой.
Скажем нормально будет
(sr.Attr and faDorectory) = faDirectory
или даже
(sr.Attr and faAnyFile) = faAnyFile

А вот
(sr.Attr and faDirectory) = sr.Attr
(sr.Attr and faAnyFile) = sr.Attr
это что то, кроме особых случаев, особенно на NTFS



 
nikkie ©   (2003-06-10 20:32) [57]

Логика в примере из хелпа некоторая есть: если снят флажок "hidden", то hidden файлы показваться не будут, если снят флажок "directory", то не будут показываться и директории.

Однако, это не означает, что если флажок "directory" стоит, то будут показаны все директории.

Так что с точки зрения кодировщика там все в порядке, а с точки зрения организации пользовательского интерфейса - то, как не надо делать.


 
nikkie ©   (2003-06-10 20:43) [58]

>Anatoly Podgoretsky
(sr.Attr and faDorectory) = faDirectory
это нормально, я согласен. а вот
(sr.Attr and faAnyFile) = faAnyFile
имхо, это всегда FALSE.


 
sniknik ©   (2003-06-10 22:46) [59]

Anatoly Podgoretsky © (10.06.03 20:30)
> Нет проблема не с левой частью, а с правой.
> Скажем нормально будет
> (sr.Attr and faDirectory) = faDirectory //точно нормально
> или даже
> (sr.Attr and faAnyFile) = faAnyFile //чуш, никогда не сработает sr.Attr никогда не равен всем ключам сразу

> А вот
> (sr.Attr and faDirectory) = sr.Attr //нормально, директории
> (sr.Attr and faAnyFile) = sr.Attr //нормально, любой тип
> это что то, кроме особых случаев, особенно на NTFS


вобще единственное почему такое условие может не сработать это если sr.Attr >= 64 (c faAnyFile). (а дело может быть совсем в другом)
Anatoly Podgoretsky © а вы неправы и настаиваете. проверьте сами.


 
sniknik ©   (2003-06-10 23:31) [60]

написал почему может не сработать условие (sr.Attr >= 64), но вроде такого нет но решил убедится.
и удивился D7 модуль SysUtils константы

{ 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;

а ведь может, и не сработать. что это за тип такой? из Linux-a чтоли? в хелпе по findfirst не упоминается наоборот в Linux нет
"Some of the file attribute constants are not valid on all platforms. For example, faVolumeID and faArchive will not work on Linux."
в общем если это виндовый новый атрибут то может и не сработать.


 
panov ©   (2003-06-10 23:41) [61]

faSymLink = $00000040 platform;

Возможно, что это
Hard Link - в NTFS 5.0
или Junction Point (точки соединения)


 
sniknik ©   (2003-06-11 00:01) [62]

panov © (10.06.03 23:41)
т.е. всетаки из виндов (возможно)
но тогда ЭниФайле уже не Эни.. и надо поправить
faAnyFile = $0000007F; для полного соответствия.


 
TCrash ©   (2003-06-11 00:15) [63]

Согласен с panov © (10.06.03 23:41), т.к. указанные вещи сами по себе имеют атрибуты больще $3F, сделай так :
if (sr.Attr and $FF)=srAttr then


 
TCrash ©   (2003-06-11 00:19) [64]

Кстати в языке Clarion константа AnyFile Равна именно $FF.
ЗЫ : Clarion - это тот же С только выглядит по-другому, а результирующий код - тот же. Винда на чем писана ?


 
nikkie ©   (2003-06-11 01:23) [65]

>sniknik
>тогда ЭниФайле уже не Эни..

эт-то точно.

>и удивился D7 модуль SysUtils константы
из WinNT.h от VC:

#define FILE_ATTRIBUTE_READONLY 0x00000001
#define FILE_ATTRIBUTE_HIDDEN 0x00000002
#define FILE_ATTRIBUTE_SYSTEM 0x00000004
#define FILE_ATTRIBUTE_DIRECTORY 0x00000010
#define FILE_ATTRIBUTE_ARCHIVE 0x00000020
#define FILE_ATTRIBUTE_DEVICE 0x00000040
#define FILE_ATTRIBUTE_NORMAL 0x00000080
#define FILE_ATTRIBUTE_TEMPORARY 0x00000100
#define FILE_ATTRIBUTE_SPARSE_FILE 0x00000200
#define FILE_ATTRIBUTE_REPARSE_POINT 0x00000400
#define FILE_ATTRIBUTE_COMPRESSED 0x00000800
#define FILE_ATTRIBUTE_OFFLINE 0x00001000
#define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x00002000
#define FILE_ATTRIBUTE_ENCRYPTED 0x00004000


>TCrash
>сделай так :
>if (sr.Attr and $FF)=srAttr then

могу предложить еще усовершенствовать этот код. вот так
if sr.Attr=sr.Attr then
или вот так
if True then
или вообще выкинуть, что АП сразу предлагал...

>ЗЫ : Clarion - это тот же С только выглядит по-другому,
знаем мы, что такое Clarion, не надо нам баки забивать...
а результирующий код - тот же. Винда на чем писана ?
ну уж не на кларионе. зуб даю.


 
Anatoly Podgoretsky ©   (2003-06-11 07:52) [66]

Я не это предлагаю, а следующее
if (sr.Attr and faDirectory)=faDirectory then
например для детектирования любых каталогов, и READONLY и HIDDEN и SYSTEM и ARCHIVE
Суть именно в правой стороне.

В самом вызове FindFirst указать аттрибуты faAnyFile и если есть подозрение, что не вернет записи с расширенными аттрибутами, то $FFFFFFFF с учетом даже дальнейшего увеличения их, но вроде бы и так вернет все записи.


 
KSergey ©   (2003-06-11 07:59) [67]

> TCrash © (11.06.03 00:19)
> ЗЫ : Clarion - это тот же С только выглядит по-другому,
> а результирующий код - тот же. Винда на чем писана ?

А Паскаль - тот же Фортран, только выглядит по-другому. И результирующий код одинаковый, уверяю.


 
Sandman25 ©   (2003-06-11 11:08) [68]

Anatoly Podgoretsky ©

Хорошо, убедили :)

Если нужно проверять на конкретный атрибут, то нуждо делать
if (sr.Attr and faDirectory) > 0 then
if (sr.Attr and faHidden) > 0 then
и т.д.

Если же у нас в маске поиска стоит "множество" атрибутов, как в примере, и нас интересуют только те файлы, в которых есть ВСЕ атрибуты из множества, то нужно делать именно так, как Вы написали.

Mask := faDirectory or faHidden;
FindFirst(..);
if sr.Attr and Mask = Mask then

Если же у нас в маске поиска стоит "множество" атрибутов, как в примере, и нас интересуют те файлы, в которых есть ХОТЯ БЫ 1 атрибут из множества, то нужно делать иначе.

Mask := faDirectory or faHidden;
FindFirst(..)
if sr.Attr and Mask > 0 then

Если же нам нужны только те файлы, в которых есть ХОТЯ БЫ 1 атрибут из множества и НЕТ таких атрибутов, которых нет в маске, то нужно делать так.
Для поиска скрытых директорий, для которых не установлен атрибут "архивный", не установлен атрибут "системный" и т.д.

Mask := faDirectory or faHidden;
FindFirst(..);
if sr.Attr = Mask then

А пример из Delphi help (if sr.Attr and Mask = sr.Attr then) имеет следующий смысл - нам нужно найти файл, в атрибутах которого нет ничего, чего не было бы в маске. При этом нас совершенно не волнует, есть ли у файла те атрибуты, которые есть в маске. То есть на самом деле мы задаем "отрицательную" маску - маску того, что нам не надо. Если мы не включили faHidden, значит, нужно исключить из рассмотрения все скрытые файлы и т.д.
Долой пример из Delphi help, ибо это плохой пример :)


 
Sandman25 ©   (2003-06-11 11:12) [69]

Ошибся.

Если же нам нужны только те файлы, в которых есть ВСЕ атрибуты из множества и НЕТ таких атрибутов, которых нет в маске, то нужно делать так.
Для поиска скрытых директорий, для которых не установлен атрибут "архивный", не установлен атрибут "системный" и т.д.

Mask := faDirectory or faHidden;
FindFirst(..);
if sr.Attr = Mask then



 
Sandman25 ©   (2003-06-11 11:15) [70]

Хотя если подумать, то получается, что пример из Delphi help не такой уж и плохой. Если мы не включили в маску faHidden и faDirectory, то значит, нам нужно все, кроме тех файлов, для которых эти биты установлены...


 
Anatoly P   (2003-06-11 12:57) [71]

Без проверки кстати работает (на XWP и на NTFS). Интересно что будет на W9x и W2000.
Насчет логов, такой результат:
File: english.mye sr.attr: 000000000002020Fileattr: 00000000000003F
File: russian.mye sr.attr: 000000000002020Fileattr: 00000000000003F

Делал так: Memo1.Lines.Add("File: "+ sr.Name+" sr.attr: "+ IntToHex(sr.Attr,15)+"Fileattr: "+ IntToHex(FileAttrs,15) );


 
han_malign ©   (2003-06-11 13:09) [72]

>000000000002020
как раз чисто NTFS-ный флажок FILE_ATTRIBUTE_NOT_CONTENT_INDEXED (выключено индексирования для файла,папки или тома)
а коснтанты faXXX введены только для добавления в фильтр поиска не добавляюмых по умолчанию файлов(каталогов) и проверки принадлежности очередного к ним(см. Anatoly Podgoretsky ©), а реальный атрибут возвращеется конкретно системный (GetFileAttributes,Find{First/Next}File - TWin32FindData.dwFileAttributes)


 
han_malign ©   (2003-06-11 13:16) [73]

function FindMatchingFile(var F: TSearchRec): Integer;
var
LocalFileTime: TFileTime;
begin
with F do
begin
while FindData.dwFileAttributes and ExcludeAttr <> 0 do
if not FindNextFile(FindHandle, FindData) then
begin
Result := GetLastError;
Exit;
end;
//пропускаем лишнее(см. ниже)
FileTimeToLocalFileTime(FindData.ftLastWriteTime, LocalFileTime);
FileTimeToDosDateTime(LocalFileTime, LongRec(Time).Hi,
LongRec(Time).Lo);
Size := FindData.nFileSizeLow;
Attr := FindData.dwFileAttributes; //нате получите атрибут со всеми левыми флагами
Name := FindData.cFileName;
end;
Result := 0;
end;

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;//вот такой изврат
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;

function FindNext(var F: TSearchRec): Integer;
begin
if FindNextFile(F.FindHandle, F.FindData) then
Result := FindMatchingFile(F) else
Result := GetLastError;
end;


 
Dok_3D ©   (2003-06-11 14:01) [74]

паритесь ...
Открою тайну, XP здесь не причем, зато причем NTFS.
Папка может иметь атрибут faSymLink = $00000040 и не иметь атрибут faDirectory = $00000010;

В общем, не знаю я почему так, но ВСЕГДА используйте только такую конструкцию:

if ((sr.Attr and SysUtils.faDirectory) <> 0) then
begin
ShowMessage("Ура я нашел файл с нужным атрибутом !")
end;


 
Sandman25 ©   (2003-06-11 15:44) [75]

Игорь Шевченко © (10.06.03 16:57)

Вот видите - даже гадая на кофейной гуще, можно найти единственное возможное объяснение :)


 
Anatoly P   (2003-06-11 15:51) [76]

nikkie © (11.06.03 01:23) натолкнул(а) на мысль и решил проверить, оказывается все просто - на этих двух компах была отключена служба индексации на том разделе, где стояла прога. Но все равно не ясно, почему с другими каталогами нет проблем


 
Игорь Шевченко ©   (2003-06-11 15:58) [77]

Sandman25 © (11.06.03 15:44)

Если времени не жалко :)

С уважением,


 
Anatoly Podgoretsky ©   (2003-06-11 16:13) [78]

Sandman25 © (11.06.03 11:08)
Ну правильно, я же и говорю, что справад и после AND должна быть нужная маска. а не sr.Attr


 
NailMan ©   (2003-06-11 16:23) [79]

И я это говорил, а мне не верили ;-)


 
Sandman25 ©   (2003-06-11 16:44) [80]

Anatoly Podgoretsky © (11.06.03 16:13)

В данном конкретном случае - нет.
В маске было faAnyFile, то есть faHidden + faDirectory + faSystem и т.д.
"Ваше" условие бы сработало только в том случае, если у файла установлены ВСЕ эти атрибуты. В то время как "физический" смысл faAnyFile - атрибут может быть любым. Даже для файла с атрибутом $00000000 if должен был срабатывать.

И он срабатывал, если у нас sr.Attr and faAnyFile = sr.Attr (0 and $3F = 0)
И НЕ срабатывал, если у нас sr.Attr and faAnyFile = faAnyFile (0 and $3F <> $3F).
Убедил?



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

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

Наверх




Память: 0.65 MB
Время: 0.02 c
11-97567
Alexander
2002-08-19 10:02
2003.06.30
Несколько вопросов и предложений ...


1-97629
_Alex_
2003-06-18 17:02
2003.06.30
Вызов формы из dll


1-97630
Term
2003-06-19 15:51
2003.06.30
Кто работал с Excel? Плиз... как задать тип границ ячейки, её


1-97582
Vihr
2003-06-18 21:12
2003.06.30
Оптимизация кода


14-97846
Nik8.
2003-06-12 22:57
2003.06.30
кто знает где здесь ошибка