IMHO.WS

IMHO.WS (https://www.imho.ws/index.php)
-   Программирование (https://www.imho.ws/forumdisplay.php?f=40)
-   -   Как вывести структуру директорий на компакт-диске. Возможно вопрос для ФАК'а (https://www.imho.ws/showthread.php?t=74771)

kot_ 01.12.2004 13:41

Как вывести структуру директорий на компакт-диске. Возможно вопрос для ФАК'а
 
Столкнулся со следующей проблемой - необходимо вывести в дерево структуру каталогов. Была написана следующая функция, рекурсивно считывающая файлы и каталоги:
Код:

void __fastcall TForm1::FoundFile(AnsiString Dir,TTreeNode *Node)
{
TSearchRec sr;
TTreeNode *NewNode;
TTreeNode *PNode;
ChDir(Dir);
PNode = tvList->Items->AddChild(Node,Dir);
PNode->ImageIndex =0;
FindFirst("*.*",faAnyFile,sr);

while(FindNext(sr)==0){
  if(sr.Name !="."&&sr.Name!=".."){
  if(sr.Attr ==faDirectory){
  FoundFile(sr.Name,PNode);
  }
  else{
  if(sr.Attr!=faDirectory){
    NewNode = tvList->Items->AddChild(PNode,sr.Name);
    NewNode->ImageIndex = 2;
  }
  }
//
 }
}
 FindClose(sr);
 ChDir("..");
}

собственно задача элементарная - считать содержимое некоторого каталога в дерево. Читает без проблем. НО! Только на жестком диске...:) После записи на болванку - прога категорически перестала выводить список - выводит одну директорию и считает ее файлом.
Проблема оказалась в следующем - атрибуты директории на компакте имеют значение не 0х010(константа faDirectory) а 0х011 - добавляется лишний бит.
То есть, если вы предполагаете использовать подобный механизм для получения списка директорий на ВСЕХ дисках должно быть вот так:
Код:

void __fastcall TForm1::FoundFile(AnsiString Dir,TTreeNode *Node)
{
....
  if(sr.Attr ==0х010||sr.Attr ==0х011){
  FoundFile(sr.Name,PNode);
  }
 .....
}

Тогда работает.
Точнее правильно так:
Код:

void __fastcall TForm1::FoundFile(AnsiString Dir,TTreeNode *Node)
{
....
  if(sr.Attr&faDirectory){
  FoundFile(sr.Name,PNode);
  }
 .....
}


CaptainFlint 02.12.2004 11:21

Это не только для компакта так будет. Сделай на жёстком диске системный, или скрытый, или read-only каталог и попробуй с ним первый вариант - он точно так же скажет, что это файл ;) Дело в том, что каждый атрибут - это отдельный бит в слове атрибутов, и каталог - только один из них. Так что даже пример
Код:

if(sr.Attr ==0х010||sr.Attr ==0х011){
в общем случае будет работать неправильно, т.к. он не учитывает возможность наличия, скажем, систенмых каталогов. Последний вариант
Код:

if (sr.Attr & faDirectory) {
наиболее корректен и работает во всех случаях. :cool:

kot_ 02.12.2004 11:53

Спасибо всем. Действительно использование битовой маски - это единственное решение.


Часовой пояс GMT +4, время: 15:34.

Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.