В последнее время в конференциях я часто замечаю вопрос "Как не получить список файлов в каталоге?" или "Как мне получить дерево каталогов с учетом большой вложенности директорий?". Попробуем разобраться в этом при помощи Delphi (выбрана в связи с большой популярностью данной среды разработки ПО и легкостью языка Object Pascal).
Для получения списка файлов (каталог - частный вариант файла с установленым атрибутом faDirectory) воспользуемся классом TSearchRec. В начале программы нам необходимо задать параметры поиска, такие как маска и аттрибуты. Строчка
i := FindFirst(Dir+'\*.*', faAnyFile, f);
задает поиск всех файлов (*.*) в каталоге, заданном переменной Dir, с любыми атрибутами (faAnyFile). В качестве результата получим 0, если файл найден, либо число отличное от нуля, при ошибке. В данной строке f - это объект TSearchRec. После этого в цикле
while (i=0) do
получаем оставшиеся файлы в каталоге:
i := FindNext(f);
После завершения поиска необходимо вызвать
FindClose(f);
Получить имя файла, его размер, атрибуты и прочую информацию можно через поля-атрибуты объекта TSearchRec: name, attr, size и т.д.
Таким образом мы получили все содержимое каталога Dir. Нам необходимо отсортировать информацию, убрав ее излишки, и пройти вглубь подкаталогов.
Убрать имена каталогов "." и ".."
Рекурсивно заходить в каталоги и получать список файлов внутри.
Достичь результат можно при помощи условия:
if (f.Name<>'.') and (f.Name<>'..') then FileList.Items.Add(f.Name);
где FileList - объект TListBox
Для использования рекурсии необходимо имеющийся у нас алгоритм поместить в процедуру (функцию) и рекурсивно вызывать ее.
В результате получим вот такой код:
procedure TMainForm.GetDir(Dir: string);
var
f : TSearchRec;
i : integer;
k : integer;
s : string;
st : SYSTEMTIME;
begin
i := FindFirst(Dir+'\*.*', faAnyFile, f);
while (i=0) do
begin
if (f.Name='.') or (f.Name='..') then
else
begin
if (f.Attr and faDirectory)<>0 then
begin
GetDir(Dir+f.Name+'\');
Application.ProcessMessages;
end
else
begin
k := Length(Path1.Text);
s := Dir+f.Name;
s := Copy(s, k, Length(s));
FileList.Items.Add(s);
end;
end;
i := FindNext(f);
end;
FindClose(f);
end;
Path1 - TEdit, который содержит начальный путь для поиска, например "C:\"
Вот так, путем несложных манипуляций получаем очень полезный алгоритм.