Отзывы о сообщении DNK (сообщение в теме «Поиск файлов. Ахтунг!!!»)

За данное сообщение: +1 Всего отзывов: 1 Положительные: +1 Отрицательные: 0
DNK
Недавно на своем живом опыте убедился, что не надо верить всему, что пишут в книжках. В справке к 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

Отзывы участников:

Ерёмин А.А.
Ерёмин А.А.
Отзыв: +1 +1
Отзыв добавлен: 14 марта 2012, 14:41

Полезную тему открыл.