Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Поиск с FindFirst и FindNext [D6, WinXP]


MixAnOL ©   (2006-07-19 13:24:00) 

Здарова всем!

Использую поиск файлов используя сабж. Алгоритм взят из справки борланда.
При этом возникают интересные моменты, например, когда я пытаюсь искать по маске "F*", то находятся даже файлы не имеющие в имени буквы F.
Долго не мог понять и обнаружил, что оказывается в записи TSearchRec есть поле-запись FindData, где в поле cAlternateFileName указывается усеченное 8-ми значное имя файла. Дык вот его значение и подходит под маску "F*".

Странность в том, что имя файла даже может быть полностью из русских букв и не содержать буквы F.

Как побороть?


MixAnOL   (2006-07-21 13:59:00) [1]


> The search includes the long and short file names


Это понятно, но почему cAlternateFileName  вообще никак не сходится с полным именем файла?


Игорь Шевченко   (2006-07-19 17:52:00) [2]

"The FindFirstFile function opens a search handle and returns information about the first file with a name that matches that the specified pattern. The search includes the long and short file names"

Об чем честно написано в документации.


MixAnOL   (2006-07-19 17:38:00) [3]


> Dimka Maslov

спасибо


Dimka Maslov   (2006-07-19 17:28:00) [4]

MixAnOL   (19.07.06 15:35) [15]
cAlternateFileName - это т.н. короткое имя файла, совместимое со старыми FAT. В FAT32 оно первыми шестью символами совпадает с длинным именем, в NTFS оно может быть любым. Проблема возникает от того, что FindFirst и FindNext работают через соответствующие устаревшие функции Windows, которые используют при писке по маске то самое короткое имя файла. Если бы они работали через ShellAPI которым, как и нам, уже всё равно, какое у файла короткое имя, то этой проблемы не возникало бы.


MixAnOL   (2006-07-19 15:35:00) [5]


> Надо производить поиск по маске *.* (поиск всех фалов) затем,
>  воспользовавшись функцие MatchesMask из модуля Masks проверять
> имя файла на соответсвие маске.

Помогло!

Но неясность с cAlternateFileName  осталась..


Dimka Maslov   (2006-07-19 15:26:00) [6]

Надо производить поиск по маске *.* (поиск всех фалов) затем, воспользовавшись функцие MatchesMask из модуля Masks проверять имя файла на соответсвие маске.


Плохиш   (2006-07-19 15:26:00) [7]


> Palladin ©   (19.07.06 14:45) [7]
> а мне понравилось столь нестандартное решение :)

А мне больше само условие понравилось "Если FindFirst вернёт не 0, то выполни FindNext!" :-)))


MixAnOL   (2006-07-19 15:09:00) [8]

к примеру, TSearchRec для директории с именем ЖАСМИН в поле cAlternateFileName содержит "F251~1"...
вот и находится эта директория по маске "F*"


MixAnOL   (2006-07-19 14:58:00) [9]


if FindFirst(IncludeTrailingBackSlash(SearchPath) + SearchMask, faDirectory, F) = 0 then
try
repeat
  if (F.Name <> '.') and (F.Name <> '..') then
      FindedDirs.Add(F.Name)
until
  FindNext(F) <> 0
finally
FindClose(F)
end;

результат тот же...


Юрий Зотов   (2006-07-19 14:54:00) [10]

> StriderMan ©   (19.07.06 14:50) [9]

Угу. Если корректно написано, то корректно и работает (даже и для for). По крайней мере, в PL/1.


StriderMan   (2006-07-19 14:50:00) [11]


> Для старых языков (Fortran, PL/1) - совершенно стандартное

неужели goto в тело цикла корректно работает? ... впрочем почему бы нет (кроме for)


Юрий Зотов   (2006-07-19 14:46:00) [12]

> Palladin ©   (19.07.06 14:45) [7]

Для старых языков (Fortran, PL/1) - совершенно стандартное.


Palladin   (2006-07-19 14:45:00) [13]

а мне понравилось столь нестандартное решение :)


Юрий Зотов   (2006-07-19 14:37:00) [14]

Вызывает подозрение вхождение в тело цикла минуя его заголовок. Попробуйте так (а маску задавайте F*.*):

if FindFirst(IncludeTrailingBackSlash(SearchPath) + SearchMask, faDirectory, F) = 0 then
try
 repeat
   if (F.Name <> '.') and (F.Name <> '..') then
       FindedDirs.Add(F.Name)
 until
   FindNext(F) <> 0
finally
 FindClose(F)
end;

Еще можно искать по маске *.*, а фильтровать через MatchesMask.


Johnmen   (2006-07-19 14:35:00) [15]

Наиинтереснейшее гоуту! :)))


Reindeer Moss Eater   (2006-07-19 14:34:00) [16]

Never jump into a loop or other structured statement, since this can have unpredictable effects.


MixAnOL   (2006-07-19 14:26:00) [17]


 if FindFirst(SearchPath+'\'+SearchMask,faDirectory,F)=0 then goto f1;
 while (FindNext(F)=0) do
   begin
f1:
     if (F.Name<>'.')and(F.Name<>'..') then
        FindedDirs.Add(F.Name);
   end;
 FindClose(F);


Указываю SearchMask="F*"


Юрий Зотов   (2006-07-19 14:18:00) [18]

> MixAnOL   (19.07.06 13:24)

Странные вещи Вы рассказываете. Логичнее предположить ошибку в коде - но где он?


Reindeer Moss Eater   (2006-07-19 14:04:00) [19]

Никак. Это оптический обман.


Наверх

Титульная страница Поиск, карта сайта Написать письмо