Модераторы: Snowy, MetalFan, bems, Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [Исходники][Delphi][Пример] Вывод списка всех файлов из каталога 
:(
    Опции темы
THandle
Дата 8.4.2008, 09:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Хранитель Клуба
Group Icon
Награды: 1



Профиль
Группа: Админ
Сообщений: 3639
Регистрация: 31.7.2007
Где: Moscow, Dubai

Репутация: 50
Всего: 372



Задание.

Вывести список всех файлов, находящихся в заданной папке и её поддиректориях.



Решение.

Код


procedure ListFilesInDirectory(Dir: string; Strings: TStrings);
var
  rSearchRec: TSearchRec;
begin
  if ((Dir = '') or (not Assigned(Strings))) then
    Exit;
  Dir := IncludeTrailingPathDelimiter(Dir);
  if FindFirst(Dir + '*.*', faAnyFile, rSearchRec) = 0 then
    try
      repeat
        if ((rSearchRec.Name <> '.') and (rSearchRec.Name <> '..')) then
          if (rSearchRec.Attr and faDirectory) <> 0 then
            ListFilesInDirectory(Dir + rSearchRec.Name, Strings)
          else
            Strings.Add(rSearchRec.Name);
      until FindNext(rSearchRec) <> 0;
    finally
      FindClose(rSearchRec);
    end;
end;



Объяснение.


Код


procedure ListFilesInDirectory(Dir: string; Strings: TStrings);



Dir - каталог из которого нужно вывести имена файлов.

Strings - список, в который будут добавлены имена всех файлов.


Код


  if ((Dir = '') or (not Assigned(Strings))) then
    exit;


Если список для имен файлов не создан или строка с директорией является пустой, то выходим из процедуры.

Код

Dir := IncludeTrailingPathDelimiter(Dir);


Если в конце строки преданной в Dir нет бэкслеша, то добавляем его.

Код

if FindFirst(Dir + '*.*', faAnyFile, rSearchRec) = 0 then


Ищем любой файл, если находим, то продолжаем работу процедуры, иначе - конец.


В цикле repeat...until делаем следующее:

Код

    repeat
      if ((rSearchRec.Name <> '.') and (rSearchRec.Name <> '..')) then
        if (rSearchRec.Attr and faDirectory) <> 0 then
          ListFilesInDirectory(Dir + rSearchRec.Name, Strings)
        else
          Strings.Add(rSearchRec.Name);
    until FindNext(rSearchRec) <> 0;




Код

if ((rSearchRec.Name <> '.') and (rSearchRec.Name <> '..')) then


Если что-то нашли, то:

Код

if (rSearchRec.Attr and faDirectory) <> 0 then
  ListFilesInDirectory(Dir + rSearchRec.Name, Strings)


Если найдена директория, то рекурсивно проводим поиск в ней, вызвав LstFilesInDirectory с соответствующими параметрами, иначе добавляем имя файла в список:

Код

        else
          Strings.Add(rSearchRec.Name);




Код


    until FindNext(rSearchRec) <> 0;


Если больше ничего не найдено, то завершаем процедуру.


Пример вызова.

На форме находятся следующие компоненты:

TButton - по нажатию кнопки и делаем вызов нашей процедуры.
TEdit - сюда вписываем путь к папке в которой надо производить поиск (например C:).
TListBox - сюда выводим имена файлов.

Код


procedure TForm1.Button1Click(Sender: TObject);
begin
  ListFilesInDirectory(Edit1.Text, ListBox1.Items);
end;



Это сообщение отредактировал(а) THandle - 4.12.2008, 15:15
PM   Вверх
Qu1nt
Дата 8.4.2008, 10:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 602
Регистрация: 13.1.2007

Репутация: 22
Всего: 50



Чтобы бы избежать [Pascal Warning]:
Код

Dir := IncludeTrailingBackslash(Dir);

меняем на
Код

Dir := IncludeTrailingPathDelimiter(Dir);


К тому же, я бы добавил в конец процедуры ListFilesInDirectory:
Код

FindClose(rSearchRec);


Это сообщение отредактировал(а) Qu1nt - 8.4.2008, 10:41
PM MAIL   Вверх
Rennigth
Дата 8.4.2008, 11:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1708
Регистрация: 21.6.2004
Где: Moscow

Репутация: 15
Всего: 76



Плюс я бы объявление процедуры сделал бы так:
Код

procedure ListFilesInDirectory(const Dir: string; Strings: TStrings);

зачем строки копировать на право на лево?...  smile  


--------------------
(* Honesta mors turpi vita potior *)
PM MAIL ICQ   Вверх
Qu1nt
Дата 8.4.2008, 11:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 602
Регистрация: 13.1.2007

Репутация: 22
Всего: 50



Rennigth, тогда не сработает IncludeTrailingPathDelimiter.
PM MAIL   Вверх
THandle
Дата 8.4.2008, 11:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Хранитель Клуба
Group Icon
Награды: 1



Профиль
Группа: Админ
Сообщений: 3639
Регистрация: 31.7.2007
Где: Moscow, Dubai

Репутация: 50
Всего: 372



Qu1nt, спасибо. Сейчас изменю. FindClose забыл, каюсь. smile 
PM   Вверх
Rennigth
Дата 8.4.2008, 12:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1708
Регистрация: 21.6.2004
Где: Moscow

Репутация: 15
Всего: 76



Цитата(Qu1nt @  8.4.2008,  11:53 Найти цитируемый пост)
Rennigth, тогда не сработает IncludeTrailingPathDelimiter. 

угумс, не заметил... но я в таких случаях доп переменную ввожу. это конечно уже дело каждого smile


--------------------
(* Honesta mors turpi vita potior *)
PM MAIL ICQ   Вверх
MetalFan
Дата 8.4.2008, 12:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 22
Всего: 128



ага, так же я бы добавил проверку на Dir <> '', ибо если придет пустышка, то начнется поиск с корня текущего диска...

Добавлено через 1 минуту и 38 секунд
а еще мне понравился подход, предложенный на sources.ru Обработчик цикла for..in по файловой системе, готовое решение для Delphi 2006 и выше


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
THandle
Дата 8.4.2008, 12:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Хранитель Клуба
Group Icon
Награды: 1



Профиль
Группа: Админ
Сообщений: 3639
Регистрация: 31.7.2007
Где: Moscow, Dubai

Репутация: 50
Всего: 372



MetalFan, оно и тут есть.

http://forum.vingrad.ru/faq/topic-179211.html

 smile 

Но это уже не совсем для новичков. 


Цитата(MetalFan @  8.4.2008,  13:13 Найти цитируемый пост)
ага, так же я бы добавил проверку на Dir <> '', ибо если придет пустышка, то начнется поиск с корня текущего диска...


Мне такой подход не очень нравится. Не люблю проверять в самой процедуре\функции.

Обычно делаю проверку и если что то не так показываю об этом сообщение. Если уж добавлять, то ИМХО, так:


Код

procedure TForm1.Button1Click(Sender: TObject);
begin
  if Edit1.Text <> '' then
    ListFilesInDirectory(Edit1.Text, ListBox1.Items);
end;


PM   Вверх
MetalFan
Дата 8.4.2008, 14:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 22
Всего: 128



Цитата(THandle @  8.4.2008,  12:45 Найти цитируемый пост)
Но это уже не совсем для новичков. 

как раз, имхо, не вдаваясь в подробности, проще и нагляднее пользоваться тем методом.
Цитата(THandle @  8.4.2008,  12:45 Найти цитируемый пост)
Мне такой подход не очень нравится.

тогда не будет предусмотрена защита от дурака.
простой пример - функция очистки директории.
на вход - путь, внутри используется твоя функция. после чего все найденные файлы удаляются.
тогда при "случайной" передаче "пустышки" очистим нафиг корень диска...
лучше уж элементарную проверку предусмотреть


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
THandle
Дата 8.4.2008, 14:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Хранитель Клуба
Group Icon
Награды: 1



Профиль
Группа: Админ
Сообщений: 3639
Регистрация: 31.7.2007
Где: Moscow, Dubai

Репутация: 50
Всего: 372



Цитата(MetalFan @  8.4.2008,  15:16 Найти цитируемый пост)
как раз, имхо, не вдаваясь в подробности, проще и нагляднее пользоваться тем методом.

Ну не знаю. Всё равно там то с 2006, а у новичков обычно 7. Пусть будет и тот пример, и этот. Тут к тому же уже ссылка на тот дана. Кому надо - посмотрят.


Цитата(MetalFan @  8.4.2008,  15:16 Найти цитируемый пост)
тогда не будет предусмотрена защита от дурака.
простой пример - функция очистки директории.
на вход - путь, внутри используется твоя функция. после чего все найденные файлы удаляются.
тогда при "случайной" передаче "пустышки" очистим нафиг корень диска...
лучше уж элементарную проверку предусмотреть 


Ладно. Тут убедил. smile Сейчас исправлю. smile 
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Для новичков"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0941 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.