_NIK_ |
Отправлено: 03.03.2006, 21:52 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 55
|
Всем привет!
Зае..ся ваще, что за глюк?
Вот код:
TSearchRec sr;
if (FindFirst(InputDir + "\*.*", faAnyFile, sr) == 0)
{
do
{
if ((sr.Name != ".")&&(sr.Name != ".."))
{
if (sr.Attr == faDirectory)
{
Utf8Encode(InputDir + "\" + sr.Name);
}
if ((sr.Attr != faDirectory)&&(sr.Attr != faVolumeID)&&(sr.Attr != faReadOnly)&&(sr.Attr != faSysFile))
{
TStringList * MyList = new TStringList;
Form1->StatusBar1->Panels->Items[0]->Text = InputDir + "\" + sr.Name;
Form1->StatusBar1->Panels->Items[2]->Text = Form1->StatusBar1->Panels->Items[2]->Text.ToInt() + 1;
Form1->Memo1->Lines->Add(InputDir + "\" + sr.Name);
}
}
} while (FindNext(sr) == 0);
FindClose(sr);
}
Почему этот алгоритм, точнее функции распознают папки у кот. настроен внешний вид за ФАЙЛЫ???
|
|
Guest |
Отправлено: 03.03.2006, 22:23 |
|
Не зарегистрирован
|
Вместо одиничной косой черты нужен двойной. Напр.
if (FindFirst(InputDir + "\\*.*", faAnyFile, sr) == 0)
Посмотри в helpe: \ (backslash) escape sequences
Note: You must use \\ to represent an ASCII backslash, as used in operating system paths. |
|
_NIK_ |
Отправлено: 03.03.2006, 22:34 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 55
|
Косые Черточки ДВОЙНЫЕ, тока почему-то здесь отображаются одинарные!
|
|
Guest |
Отправлено: 04.03.2006, 01:28 |
|
Не зарегистрирован
|
Ok. Пусть будет, что система виновата...
if ((sr.Attr != faDirectory)&&(sr.Attr != faVolumeID)&&(sr.Attr != faReadOnly)&&(sr.Attr != faSysFile))
Нужно, что то типа
if((sr.Attr&faDirectory != faDirectory)....
|
|
_NIK_ |
Отправлено: 04.03.2006, 17:47 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 55
|
Пробовал...им ваще пофиг какой параметр attr в функции FindFirst и так тож не катит.
Остановился на проверке DirectoryExists(), и рекурсии в блоке:
TStringList * MyList = new TStringList;
Form1->StatusBar1->Panels->Items[0]->Text = InputDir + "\" + sr.Name;
Form1->StatusBar1->Panels->Items[2]->Text = Form1->StatusBar1->Panels->Items[2]->Text.ToInt() + 1;
Form1->Memo1->Lines->Add(InputDir + "\" + sr.Name);
условие убрал поставил else — работает
Отредактировано _NIK_ — 04/03/2006, 17:47
|
|
AVC |
Отправлено: 06.03.2006, 09:17 |
|
Ветеран
Группа: Модератор
Сообщений: 1583
|
QUOTE |
Почему этот алгоритм, точнее функции распознают папки у кот. настроен внешний вид за ФАЙЛЫ???
if (sr.Attr == faDirectory)
|
Как писал гость
CODE |
Attributes can be combined by or-ing their constants or values.
|
Это условие может не выполняться если каталог не имеет атрибут исключительно faDirectory
Во втором условии то же небходимо использовать сравнение после маскирования. |
|
Grigoriy |
Отправлено: 06.03.2006, 15:07 |
|
Мастер участка
Группа: Участник
Сообщений: 381
|
Когда-то я пользуясь этими функциями хотел проверить, как найти самому нужные файлы и каталоги.
Оказывается в файловой системе в каждом каталоге присутствуют каталоги с именами
"."
".."
Пришлось предусмотреть условие, чтобы их пропустить.
Зачем эти каталоги нужны ?
И вообще некоторые каталоги не были ни скрытыми ни системными, но помимо атрибута "faDirectory" имели другой атрибут, который могут иметь файлы, но не означающий, что они скрытые или системные.
То есть, как будто над каталогами этими можно было выполнять чтение так же как и над файлами.
|
|
Guest |
Отправлено: 06.03.2006, 15:19 |
|
Не зарегистрирован
|
QUOTE |
Оказывается в файловой системе в каждом каталоге присутствуют каталоги с именами
"."
".."
Пришлось предусмотреть условие, чтобы их пропустить.
Зачем эти каталоги нужны ?
|
Для однообразия и упрощения переходов по дереву каталогов
"." — означает текущий каталог и ссылается на себя
".." — означает "шаг назад" и ссылается на родителя |
|
_NIK_ |
Отправлено: 06.03.2006, 17:18 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 55
|
QUOTE (Guest @ 06/03/2006, 15:19) | QUOTE |
Оказывается в файловой системе в каждом каталоге присутствуют каталоги с именами
"."
".."
Пришлось предусмотреть условие, чтобы их пропустить.
Зачем эти каталоги нужны ?
|
Для однообразия и упрощения переходов по дереву каталогов
"." — означает текущий каталог и ссылается на себя
".." — означает "шаг назад" и ссылается на родителя |
Прикольно у меня получилось, когда я не делал проверку на "." и ".." в рекурсии получался бесконечный цикл
|
|
Doga |
Отправлено: 06.03.2006, 17:52 |
|
Мастер участка
Группа: Участник
Сообщений: 575
|
А я не пользуюсь рекурсионными вызовами при просмотре каталогов. Всё делает одна простая функция. Случай был один. Одно чучело на компе которого стояла наша прога, каким то образом умудрилось скопировать несколько каталогов на диске в них же самих, пока ситема позволяла... Так вот, во время сканирования тех каталогов периодически вылетал "StackOverflow" и только на том компе. В коде разбирался долго и ничего не нашёл. А когда выяснилось, все просто попадали состульев , но меры приняли, о чём собственно я и сказал выше...
|
|
Grigoriy |
Отправлено: 06.03.2006, 18:09 |
|
Мастер участка
Группа: Участник
Сообщений: 381
|
QUOTE (Guest @ 06/03/2006, 15:19) |
Для однообразия и упрощения переходов по дереву каталогов
"." — означает текущий каталог и ссылается на себя
".." — означает "шаг назад" и ссылается на родителя |
Во спасибо.
|
|
Guest |
Отправлено: 06.03.2006, 18:24 |
|
Не зарегистрирован
|
QUOTE |
А я не пользуюсь рекурсионными вызовами при просмотре каталогов. Всё делает одна простая функция. Случай был один ...
|
А какая разница рекурсивная или нет если дерево "закольцовано"? Для такого случая можно пользоваться максимальной глубиной вложенности: предел превышен — кольцо. Или анализировать весь пройденный путь, можно поробовать сыграть значениях полей TSearchRec. |
|
_NIK_ |
Отправлено: 07.03.2006, 01:55 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 55
|
QUOTE (Doga @ 06/03/2006, 17:52) | А я не пользуюсь рекурсионными вызовами при просмотре каталогов. Всё делает одна простая функция. Случай был один. Одно чучело на компе которого стояла наша прога, каким то образом умудрилось скопировать несколько каталогов на диске в них же самих, пока ситема позволяла... Так вот, во время сканирования тех каталогов периодически вылетал "StackOverflow" и только на том компе. В коде разбирался долго и ничего не нашёл. А когда выяснилось, все просто попадали состульев , но меры приняли, о чём собственно я и сказал выше... |
А какой функцией пользуешься?
|
|
_NIK_ |
Отправлено: 07.03.2006, 01:58 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 55
|
QUOTE (Guest @ 06/03/2006, 18:24) | QUOTE |
А я не пользуюсь рекурсионными вызовами при просмотре каталогов. Всё делает одна простая функция. Случай был один ...
|
А какая разница рекурсивная или нет если дерево "закольцовано"? Для такого случая можно пользоваться максимальной глубиной вложенности: предел превышен — кольцо. Или анализировать весь пройденный путь, можно поробовать сыграть значениях полей TSearchRec. |
Как понять "дерево закольцовано"?
И предел вложенности нельзя использовать — не все файлы найдет!
|
|
Doga |
Отправлено: 07.03.2006, 08:13 |
|
Мастер участка
Группа: Участник
Сообщений: 575
|
Вот кусок кода. Не гарантирую что в таком виде он будет работать, поскольку я убрал оттуда "всё лишнее" , но для демонстрации способа сгодится .
Вообще то ето тело функции TThread:Execute. В конструктор потока передаются 3 параметра:
1. TStringList *FPathList;
2. Bool FFindBelow;
3. AnsiString FFileMask;
(ну может что ещё...)
В FPathList можно записывать любые пути, вплоть до списка дисков...
CODE |
//---------------------------------------------------------------------------
void __fastcall TMonitorThread::Execute()
{
//---- Place thread code here ----
int i,j,k;
TSearchRec sr;
AnsiString MaskNameString;
if(FPathList)
{
if ( FPathList->Count > 0 )
{
//А может пути неверныя?
for (int i = 0; i < FPathList->Count; i++)
{
if (!DirectoryExists(FPathList->Strings[i]))
{
FPathList->Delete(i);
i--;
}
}
}
}
else //if(!FPathList)
{
return;
}
//А таперя — поиск всех доступных путёв на всех доступных дисках во всех даступных путях!
for (i = 0; i < FPathList->Count; i++)
{
if (Terminated)
{
break;
}
//Корректировка пути(дабавлямс '\')
FPathList->Strings[i] = NormalDir(FPathList->Strings[i]);
//А ща MaskNameString — енто будет строка с маской имени файла(вааще-то каталога)
MaskNameString = FPathList->Strings[i] + "*.*";
//Поиск всех подкаталогов в выбраном каталоге
for ( j = 0;;j++) //здесь лучша использовать while, но мне был нужен счётчик j
{
if (Terminated)
{
break;
}
if (!j)
{
if (FindFirst(MaskNameString, faAnyFile, sr))
{
FindClose(sr);
break;
}
}
else
{
if (FindNext(sr))
{
FindClose(sr);
break;
}
}
//Добавлямс новый путь к списку (ежели енто каталог)
if(sr.Attr&faDirectory)
{
//Ежежели енто, канюшно, разрешено
if(FFindBelow == true)
{
if((sr.Name != ".") && (sr.Name != ".."))
{
k = FPathList->Add(FPathList->Strings[i] + sr.Name);
FPathList->Strings[k] = FPathList->Strings[k].Unique();
}
}
}
//А коли файла папаласи — устроим ей тут жа праверку на вшивость
else if(!(sr.Attr&FBadAttributes))
{
//Таперя проверим, а не совпадает ли найденный файл с
//нужной маской поиска — FFileMask
if (MatchesMask(sr.Name, FFileMask))
{
//собственно здесь производятся необходимые действия с найденным файлом...
}
}
}
}
if(FPathList)
{
delete FPathList;
FPathList = NULL;
}
}
//---------------------------------------------------------------------------
|
|
|