Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Файловая система
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 11.06.2012, 21:15
PRStudio PRStudio вне форума
Прохожий
 
Регистрация: 18.02.2012
Сообщения: 13
Репутация: 143
По умолчанию Получить список всех папок, включая системные, скрытые и т.д.

И так, продолжаю список статей, "курсовую сдавать через три дня, а все работает криво и не так как надо, или не работает вообще" )

Столкнулся с еще одной проблемой при написании своего "Антивируса". Для построения списка папок я использую FindFirst, FindNext ... Но вот почему-то некоторые папки он причисляет к файлам, такие как C:\ProgramFiles, C:\Users и т.д., т.е. скрытые или системные папки попадают в список файлов, мой алгоритм пытается взять их хеш-сумму и естественно выдает ошибку.

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

Алгоритм, который работает (почти) в данный момент:

Код:
    found := FindFirst(startPoint+'\*',faAnyFile,foundFolders);
    if (found = 0) Then begin
    while (found = 0) do begin
      if ((foundFolders.Name <> '.') and (foundFolders.Name <> '..')) Then begin
        if (foundFolders.Attr and faDirectory) = faDirectory  Then Begin
          Application.ProcessMessages;
          currentPath := startPoint + '\' + foundFolders.Name;
          setLength(allFolders,Length(allFolders)+1);
          allFolders[Length(allFolders)-1]:=currentPath;
          sGetFoldersListFromStartPoint(currentPath);
        end;
      end;
      found := FindNext(foundFolders);
    end;
    findClose(found);
    end;

где
found - состояние функции
foundFolders- запись TSearchRec
allFolders - массив с папками

Как видно, я пытаюсь отсеять все и оставить только папки, но сюда не пролезают такие папки как c:\program files и т.д., напротив, эти папки пролезают в алгоритм, который должен оставить только файлы и затем взять их хеш-сумму, благо поставил try-except который и отлавливает вылетающие ошибки при попытке взять хеш от папки.
Ответить с цитированием
  #2  
Старый 11.06.2012, 21:47
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,055
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Попробуй так:
Код:
if (foundFolders.Attr and faDirectory) <> 0  Then Begin
Ответить с цитированием
  #3  
Старый 11.06.2012, 22:21
PRStudio PRStudio вне форума
Прохожий
 
Регистрация: 18.02.2012
Сообщения: 13
Репутация: 143
По умолчанию

А, да, забыл исправить после экспериментов, у меня было
Код:
if (foundFolders.Attr = faDirectory) Then...
Imikle, к сожалению это тоже не решило проблему, папки помеченные "только для чтения" и/или "скрытый" по-прежнему отсекаются и попадают потом в другой список как файлы.
Ответить с цитированием
  #4  
Старый 11.06.2012, 22:40
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Так не забывай проверять и на остальные атрибуты. Ищешь с атрибутом faAnyFile, далее проверяешь что нашёл.
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
Ответить с цитированием
  #5  
Старый 12.06.2012, 16:20
PRStudio PRStudio вне форума
Прохожий
 
Регистрация: 18.02.2012
Сообщения: 13
Репутация: 143
По умолчанию

Сделал, пришлось много поэкспериментировать.
В Delphi маски доступа имеют вид:
Код:
только чтение  0000001
Скрытый        0000010
Системный      0000100
Волум          0001000
директория     0010000
Архив          0100000
Линк           1000000

Некоторые папки windows имеют 14-битовые маски доступа (например 10010000010110), пришлось брать существующие маски, переводить их в двоичную, затем дополнять нулями, а потом выбирать бит папки. Если бит есть - значит это папка )

Реализация:

Код:
function decToBin(dec:Integer):String;
  var ost:Integer;
      del:Integer;
      bin:String;
  begin
    while (dec >= 2) do begin
      ost := dec mod 2;
      dec := dec div 2;
      bin := IntToStr(ost) + bin;
    end;
    bin := IntToStr(dec) + bin;
    decToBin := bin;
  end;

  function fillBin(bin:String):String;
  var binLen:Byte;
      i:Byte;
  begin
    binLen := Length(bin);
    if (binLen <> 14) Then begin
      for i:= 1 to 14 - binLen do begin
        bin := '0' + bin;
      end;
      fillBin := bin;
    end else
      fillBin := bin;
  end;

  function folderAttr(attrValue:Cardinal):Boolean;
  var attr:String;
  begin
    attr := decToBin(attrValue);
    attr := fillBin(attr);
    if (attr[10] = '1') Then
      folderAttr := True
    else
      folderAttr := False;
  end;

Функция folderAttr возвращает TRUE если атрибут соответствует директории, FALSE если нет.
Ответить с цитированием
  #6  
Старый 12.06.2012, 21:40
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Здорово, но всё это делается гораздо проще. За примерами далеко ходить не нужно, посмотри исходники Дельфи.
Один из вариантов проверки показал lmikle.
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
Ответить с цитированием
  #7  
Старый 13.06.2012, 09:38
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

Код:
var
  ASearchRec: TSearchRec;
begin
  if FindFirst('c:\*.*', faAnyFile, ASearchRec)=0 then
  begin
    repeat
      if (ASearchRec.Attr and faDirectory)<>0 then
        Memo1.Lines.Add('['+ASearchRec.Name+']')
      else
        Memo2.Lines.Add(ASearchRec.Name);
    until FindNext(ASearchRec)<>0;
    FindClose(ASearchRec);
  end;
end;
все честно!
__________________
Пишу программы за еду.
__________________

Последний раз редактировалось NumLock, 13.06.2012 в 09:41.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 01:05.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter