Форум Программирование Поиск файлов. Ахтунг!!! |
Страницы: «1» «2» | ||||||||
|
Недавно на своем живом опыте убедился, что не надо верить всему, что пишут в книжках. В справке к Delphi 7 присутствует описание примера поиска файлов Цитата: Delphi Object and Component Reference FindFirst, FindNext, FindClose example ------------------------------------------------------------------------------------ The following example uses an edit control, a button, a string grid, and seven check boxes. The check boxes correspond to the seven possible file attributes. When the button is clicked, the path specified in the edit control is searched for files matching the checked file attributes. The names and sizes of the matching files are inserted into the string grid. procedure TForm1.Button1Click(Sender: TObject); var sr: TSearchRec; FileAttrs: Integer; begin StringGrid1.RowCount := 1; if CheckBox1.Checked then FileAttrs := faReadOnly else FileAttrs := 0; if CheckBox2.Checked then FileAttrs := FileAttrs + faHidden; if CheckBox3.Checked then FileAttrs := FileAttrs + faSysFile; if CheckBox4.Checked then FileAttrs := FileAttrs + faVolumeID; if CheckBox5.Checked then FileAttrs := FileAttrs + faDirectory; if CheckBox6.Checked then FileAttrs := FileAttrs + faArchive; if CheckBox7.Checked then FileAttrs := FileAttrs + faAnyFile; with StringGrid1 do begin RowCount := 0; 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; end; end; Началось история с того, что наши пользователи начали переходить на W7 и взяли моду работать под ограниченным пользователем. Это само собой плачевно сказывается на попытках программы сохранить какие либо данные в установочную дирректорию. Самым логичным оказалось перенаправить эту деятельность в личную директорию пользователя (c:\Users\User\AppData\Roaming\, но меня ждал сюрпиз: все алгоритмы поиска файлов стали выдавать 0 файлов. Эти алгоритмы были написаны не мной, но в чистой классике жанра (возможно даже скопипастщины). Как показал дебаг, всё дело в конструкции if (sr.Attr and FileAttrs) = sr.Attr then. По не совсем понятным мне причинам все файлы в личной папке пользователя имеют в атрибуте кроме младшего байта ненулевое значение и в байте постарше. Если в остальных директориях например для директорий sr.Attr был равен $00000010, то в личной папке пользователя он оказывается равен $00002010. Соответсвенно операция ($00002010 and $00000010) = $00002010 никогда не будет правдивой. Исправил ситуацию заменой конструкции на: if (sr.Attr and FileAttrs) <> 0 then "Digital Networked Knight" | |||||||
|
Могу ошибаться, но по-моему компилятор выдавал предупреждение, что данные зависят от установленной ОС. Может и не в поиске, но где-то при работе с файлами точно встречался. | |||||||
|
"... is specific to a platform"? Не было такого. Конкретно я такую ругарь видел только на модуль FileCtrl, а функции поиска используют SysUtils. Да даже если и так, ты как-то по другому список файлов получаешь? "Digital Networked Knight" | |||||||
|
Цитата (DNK): Конкретно я такую ругарь видел только на модуль FileCtrl Вполне возможно. Я помню, что видел где-то в местах, связанных с файлами. Цитата (DNK): Да даже если и так, ты как-то по другому список файлов получаешь? Нет. Это уже камни, о которых никто не предупредил. Спасибо за информацию! | |||||||
|
Сам ты ахтунг Этому [кривенькому] примеру поболее 15 лет будет А тот бит, который всю Delphi-малину поломал присутствует тоже уже много лет виконання програми розпочинається з того самого мiсця, де призупинилося. | |||||||
|
И всё таки я хотел заострить на нем внимание. Работаю с Delphi больше 10 лет, а о такой тонкости узнал впервые и уверен многие о ней до сих пор не подозревают. За ссылку спасибо. "Digital Networked Knight" | |||||||
|
Да нет же здесь никакой тонкости. Есть неряшливый старый код, который когда-то работал, а теперь сломался. Он сломался бы и раньше, если бы кто-то озаботился его протестировать. виконання програми розпочинається з того самого мiсця, де призупинилося. | |||||||
|
if (sr.Attr and FileAttrs) = sr.Attr thenА кто сказал, что этот код верный? он точно неверный и от винды это мало зависит. Просто раньше везло. Если присмотрется, то этот код эквивалентный такому if sr.Attr = FileAttrs thenВ условии задачи ведь говорится, что код будет искать файлы, которые имеют указанные атрибуты. Но кто мешает файлам иметь другие атрибуты. А хотелось проверить, что файл имеет эти атрибуты, и возможно другие. Ну тогда зачем добавлять условие??? findfirst и так все правильно отберет. with StringGrid1 do begin RowCount := 0; if FindFirst(Edit1.Text, FileAttrs, sr) = 0 then begin repeat RowCount := RowCount + 1; Cells[1,RowCount-1] := sr.Name; Cells[2,RowCount-1] := IntToStr(sr.Size); until FindNext(sr) <> 0; FindClose(sr); end; end;Но да, некоторые любят писать перестраховочный код. Но писать его не могут. Галочка "подтверждения прочтения" - вселенское зло. | |||||||
|
Я может чего-то не догоняю. У меня Delphi глубоко накласть, какой атрибут передают в FindFirst. Указываю искать только каталоги, но всё равно находятся и обычные файлы удовлетворяющие текстовой маске. Цитата (Вадим К): Если присмотрется, то этот код эквивалентный такому А в случае faAnyFile?if sr.Attr = FileAttrs then "Digital Networked Knight" | |||||||
|
Читаем, ужасаемся http://xydan.livejournal.com/2762.html Галочка "подтверждения прочтения" - вселенское зло. | |||||||
Перейти в раздел:
© 2004 - 2025, Delphi.int.ru |
Версия форума: 1.10 (19.01.2010) |
Выполнено за 0.03 сек. |