Вверх ↑
Этот топик читают: Гость
Ответов: 9906
Рейтинг: 351
#1: 2012-08-28 11:01:20 ЛС | профиль | цитата
Не нравится мне сия рекурсия (реальных ошибок пока не искал)


#pas
procedure THIFileSearch.Search;
var FindHandle:THandle;
begin
FindHandle := FindFirstFile(PChar(Dir + '*.*'), FindData);
if FindHandle=INVALID_HANDLE_VALUE then exit;
repeat if (PChar(@FindData.cFileName[0]) <> '.')and(PChar(@FindData.cFileName[0]) <> '..') then
if (FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY)<>0 then begin
if _prop_Include > 0 then OutFiles(Dir,FindData.cFileName);
if _prop_SubDir = 0 then Search(Dir + FindData.cFileName + '\'); // Вот здесь и не нравится !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
end else if StrCmp(LowerCase(FindData.cFileName),FWorkExt) then begin
inc(FCount);
if _prop_Include <> 1 then OutFiles(Dir,FindData.cFileName);
end else _hi_OnEvent(_event_onOtherFiles,Dir + FindData.cFileName);
until FStop or not FindNextFile(FindHandle, FindData);
FindClose(FindHandle);
end;

Но все равно - есть предложение подстраховаться (см. аттач)
карма: 9

0
Разработчик
Ответов: 26149
Рейтинг: 2127
#2: 2012-08-28 11:17:06 ЛС | профиль | цитата
Galkov писал(а):
есть предложение подстраховаться

А как эта подсраховка поведет себя в плане быстродействия на большом кол-ве файлов
Если не сильно скажется, то вполне можно добавить в исправления
карма: 22

0
Ответов: 9906
Рейтинг: 351
#3: 2012-08-28 13:05:37 ЛС | профиль | цитата
Ну на все вопросы ответа у меня нет, конечно же.
Но тут работает не количество файлов, а глубина вложенности папок (при включенном SubDir)
Типа: если глубина 1000 -- ну значит 1000 раз эта суета и случится.


Кстати говоря, я несколько непрофессионально "подстраховался", копированием-то. Поспешил...
Надо менять указатель на структуру, а не копировать ее.
Примерно так
карма: 9

1
файлы: 1hifilesearch1.rar [1KB] [366]
Голосовали:Tad
Разработчик
Ответов: 26149
Рейтинг: 2127
#4: 2012-08-28 13:28:23 ЛС | профиль | цитата
Galkov писал(а):
Надо менять указатель на структуру, а не копировать ее

Что-то я не совсем понял -- а где происходит восстановление указателя, или тут некоторый другой механизм?


  Self.FindData := @FindData;
repeat if FindData.cFileName[0] <> '.' then
if (FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY)<>0 then begin
if _prop_Include > 0 then OutFiles(Dir,FindData.cFileName);
if _prop_SubDir = 0 then begin
Search(Dir + FindData.cFileName + '\');
Self.FindData := @FindData;
end
Те где обращение к Self.FindData, оно только перезаписывается, а где читается
карма: 22

0
Ответов: 9906
Рейтинг: 351
#5: 2012-08-29 08:01:06 ЛС | профиль | цитата
nesco писал(а):
Что-то я не совсем понял -- а где происходит восстановление указателя, или тут некоторый другой механизм?

из разумно приведенного тобой фрагмента:
Первая строка - сохранение указателя на структуру в поле объекта, чтобы народ мог пользоваться результатами (через точки Count и ShortName)
Сама структура - локальная переменная (т.е. лежит в стеке и размером эдак так байт 300)
Рекурсивный вызов метода Search (3-я строка снизу) изменит этот указатель на новую структуру из стека.
Закончили рекурсию (т.е. обработку папки), надо восстанавливать. Ну вот же вторая строка снизу -- она не просто тупо пишет то же самое, а именно восстанавливает. Потому что указатель был изменен рекурсивным вызовом (и, кстати говоря, уже не действительный)

Собственно, все мои опасения и заключались в том, что рекурсивный вызов изменил структуру TWin32FindData, а мы продолжаем им пользоваться далее (скажем в FindNextFile) как будто ничего не произошло.
Руку на отсечение не дам, что Билл не предусмотрел такие заморочки в своих FindXXXX-ах ... Но если и предусмотрел, то никому ничего не сказал. Типа -- я в MSDN про это ничего не нашел.

карма: 9

0
Разработчик
Ответов: 26149
Рейтинг: 2127
#6: 2012-08-29 10:41:13 ЛС | профиль | цитата
Galkov писал(а):
чтобы народ мог пользоваться результатами

Все, дошло, понял для чего и как. Остальное все уже понятно. И докопался же ты до возможности появления такой траблы
карма: 22

0
Ответов: 4630
Рейтинг: 749
#7: 2012-08-29 11:57:56 ЛС | профиль | цитата
Galkov, раз ты уже покопался в глубинах FileSearch, интересно было бы услышать твое мнение в этой теме: Недоделка в FileSearch
карма: 26

0
Ответов: 9906
Рейтинг: 351
#8: 2012-08-29 12:55:42 ЛС | профиль | цитата
Согласен с коллегами в следующем:

1) Уверен, что именно так и было: дописали метод (кому-то вдруг понадобилось OtherFiles), а про св-во FullName просто позабыли. И позволили себе "позабыть", потому что исправить - проблем-то никаких.
2) Вплыло "только сейчас" не из-за извращенной логики старттопера, а ИМЕННО потому, что редко пользуются. Нормальная логика-то, как раз. Правильная, как мне кажется.
3) Раз не сказано нигде в хинтах про "область использования" FullName - то любой нормальный нормальный человек применит в уме его к обоим выходным событиям, и будет маюгаться, обнаружив обратное. Tad прав на 101%. В общем (учитывая п.2), проблемы обратной совместимомости я оцениваю как крайне незначительные (как исчезающе малые).


Ничего личного, меня спросили - я ответил
Да, и спасибо коллегам за ссылку. А то поиском заниматься - нет ни времни, ни привычки
карма: 9

0
Ответов: 4630
Рейтинг: 749
#9: 2012-08-29 12:59:04 ЛС | профиль | цитата
Galkov, спасибо.
карма: 26

0
Ответов: 16884
Рейтинг: 1239
#10: 2012-08-29 13:16:04 ЛС | профиль | цитата
Добавлю. Netspirit, в теме: Недоделка в FileSearch
nesco писал(а):
Нет, не правильно, имена могут начинаться с цифры, вот тогда бардак и начнется
тут nesco не прав - двойной слеш нужен только для нашего CodeGen-а на этапе создания кодов для компиляции и совершенно по барабану для работающей программы.
Galkov,я бы ещё поменял местами строки
procedure THIFileSearch._work_doSearch;
var Dr:String;
begin
Dr := ReadString(_Data,_data_Dir,_prop_Dir);
FWorkExt := LowerCase(ReadString(_Data,_data_Ext,_prop_Ext));
if Dr = ' then exit;
..................
на
procedure THIFileSearch._work_doSearch;
var Dr:String;
begin
Dr := ReadString(_Data,_data_Dir,_prop_Dir);
if Dr = ' then exit;
FWorkExt := LowerCase(ReadString(_Data,_data_Ext,_prop_Ext));
..................
карма: 25
Немного терпения! Дежурный экстрасенс скоро свяжется с Вами!
0
Разработчик
Ответов: 26149
Рейтинг: 2127
#11: 2012-08-29 13:22:24 ЛС | профиль | цитата
Tad, к чему это Я убрал давно уже лишний слэш
карма: 22

0
Ответов: 9906
Рейтинг: 351
#12: 2012-08-29 13:56:38 ЛС | профиль | цитата
0
карма: 9

0
Разработчик
Ответов: 26149
Рейтинг: 2127
#13: 2012-08-29 14:33:27 ЛС | профиль | цитата
0
карма: 22

0
Ответов: 9906
Рейтинг: 351
#14: 2012-08-29 14:56:05 ЛС | профиль | цитата
Ну да, правильно.

Но, nesco, главное правило Инженера - никому не верить
Прокрути сам у себя все в голове. Оба кода выполняют одни и те же манипуляции -- как с данными, так и со стеком. Это мое утверждение такое...
Ты прокрутил... Я прокрутил... Предположим, что вероятность ошибиться у нас у каждого -- 1%.
Тогда, если мы оба прокрутили, вероятность ошибки -- всего 0.01%

Мне еще время нужно на окончательно подумать... Может и фигня с +#0 -- следствие моей тупости с OR-ом...
карма: 9

0
Разработчик
Ответов: 26149
Рейтинг: 2127
#15: 2012-08-29 15:12:19 ЛС | профиль | цитата
Насколько я так понял, то вся старая конструкция следствие этого OR-a
карма: 22

0
Сообщение
...
Прикрепленные файлы
(файлы не залиты)