Програмний пошук файлів на Delphi (исходники), Різне, Програмування, статті

У цьому уроці ми з вами ознайомимося з основними принципами програмної організації пошуку файлів. Для початку визначимося, навіщо нам це може бути потрібно. Наприклад, вам потрібно при запуску програми на виконання просканувати певний каталог на присутність DOC файлів, і при наявності таких відкрити їх на редагування або надрукувати. А як вам така ідея: фоновий пошук EXE файлу в мережі, і при виявленні нової версії, автоматичне оновлення.

Багатьом відомі програми, де можна шукати файли, правила пошуку файлу. Файли можна шукати як з файлових командирах (Нортон, вовків, дос навігатор, фар), так в будь-якій операційній системі. В операційній системі windows діалогове вікно пошуку файлу викликається “Пуск” – “Пошук” – “Файли та папки”. У вікні необхідно задати умову шуканого файлу (назва, маска) і шлях початкового пошуку (каталог). На інших вкладках цього діалогового вікна можна розширити можливості пошуку по даті зміни, за що міститься тексту, за розміром.



Згадаймо правила пошуку файлів. Ви можете задати як ім’я шуканого файлу, так і його маску, якщо назва невідомо чи необхідно знайти кілька. Тобто застосовуючи спеціальний шаблон пошуку, ви можете організувати умови вибірки знайдених файлів. Відразу обмовлюся, що пошук можна застосовувати як до файлів, так і до каталогів. Будемо їх називати елементами файлової системи. У шаблон маски шуканих елементів може входити:



  1. Літери і цифри в назві та розширенні.

  2. Символ * (зірочка, математичний знак “помножити”), який замінює будь-яку кількість всіляких букв і цифр у назві або розширенні.

  3. Символ? (Знак питання), що заміняє одну букву або цифру в назві або розширенні шуканого елемента.

Наприклад, ви шукайте всі текстові файли з розширенням TXT. В поле імені шуканого файлу вам потрібно ввести “*. TXT” (пишеться без лапок) і система знайде всі такі файли в зазначеному диску або каталозі. Якщо вам треба знайти всі файли з назвою semen, то в поле пошуку файлу потрібно ввести “semen. *”. Якщо вам потрібно знайти елементи з третьої буквою k і з першою буквою t в розширенні, то вводите “?? K *. T *”. Тут знак питання вказує на будь-який символ, третім символом по порядку йде буква k, далі назва файлу (каталогу) може складатися з будь-якої кількості букв і цифр, вказуємо зірочку. В розширеним першим буква t, далі слід будь-яке розширення.
Примітка: файли і каталоги в операційній системі windows шукаються без обліку регістра, тобто рядкові і великі літери не розрізняються.


Тепер розглянемо програмний пошук файлів за допомогою мови програмування object pascal.

Вся організація циклу пошуку, а саме це і є цикл з продовженням пошуку, зводиться до:



  1. Завдання умов пошуку. Це каталог і маска шуканого елемента або елементів, атрибути елемента (ів). При завданні умов пошуку відразу відбувається пошук першого підходящого під умову. Це функція FindFirst.

  2. Продовження пошуку наступного елемента по заданих в першому пункті умов. Це функція FindNext і вона може викликатися скільки завгодно разів, поки всі файли і каталоги, що задовольняють умові, не будуть знайдені.

  3. Закриття пошуку і звільнення пам’яті, що виділяється системою під пошук. Команда FindClose.

Функція FindFirst


Синтаксис:

FindFirst  (КАТАЛОГ_ПОИСКА_И_МАСКА_ФАЙЛА,  АТРІБУТИ_ІСКОМОГО_ФАЙЛА, ПОІСКОВОЯ_ПЕРЕМЕННАЯ);

де: Каталог для пошуку і маска шуканого елемента – строкова величина, що має тип String, може, наприклад, утримувати “c: *. *” – всі елементи в корені диска С. Зверніть увагу, що вказується повний шлях для пошуку.

Атрибути шуканого елемента це користувацькі або системні атрибути, які може мати файл (каталог, мітка диска). Ось їх перелік:



Якщо вам потрібно шукати тільки елементи, що мають атрибут “каталог” і “прихований”, то можна застосувати знак математичного складання, наприклад faDirectory + faHidden.


Пошукова змінна має тип TSearchRec. У неї, при успішному результаті пошуку, буде занесено всі необхідні дані про знайдений файловому елементі.

Оскільки FindFirst є функцією, то вона повинна сама повертати деяке значення. Це значення має тип Integer і означає результат пошуку файлу (код помилки пошуку). Якщо файл знайдений, то приймає нульове значення.

Функція FindNext


FindNext (ПОІСКОВАЯ_ПЕРЕМЕННАЯ);

Ця функція продовжує пошук, заданий у функції FindNext. Повертає значення результату пошуку (нульове в разі успішного пошуку).

Процедура FindClose


FindClose (ПОІСКОВАЯ_ПЕРЕМЕННАЯ);

Закриває пошук і звільняє пам’ять, виділену системою під пошук.

Тепер розглянемо приклад. Припустимо, нам треба знайти всі файли і каталоги в каталозі DELPHI, що знаходиться на диску C:. В подальшому, ви можете самостійно, змінюючи маску, змінювати умови пошуку. Для форми з компонентом ListBox1 і кнопкою Button1 реакція на OnClick по кнопці:

procedure TForm1.Button1Click(Sender: TObject); Var SR: TSearchRec; / / Пошукова мінлива  FindRes: Integer; / / мінлива для запису результату пошуку
begin ListBox1.Clear; / / очищення компонента ListBox1 перед занесенням до нього списку файлів FindRes: = FindFirst (“c: delphi *. *”, FaAnyFile, SR); / / завдання умов пошуку і початок пошуку While FindRes = 0 do / / поки ми знаходимо файли (каталоги), то виконувати цикл
begin ListBox1.Items.Add (SR.Name); / / додавання в список назву знайденого елемента FindRes: = FindNext (SR); / / продовження пошуку по заданих умов
end; FindClose (SR); / / закриваємо пошук
end;

Представлений приклад коду, в принципі, є основою для організації більш поглибленого пошуку, пошуку файлів за часом створення, за що містяться словами. Якщо ви запустите цю програму на виконання, то при натисненні на кнопку Button1 ви побачите в списку в першій і другій рядку елементи “.” і “..”. Це елементи, що мають атрибут “каталог”. Перший містить зв’язок з кореневим каталогом диска, другий містить зв’язок до каталогом верхнього рівня. З другим ви зустрічаєтеся в дискових командних оболонках, наприклад Нортон, коли вибираєте каталог “..” і натискаєте на “вхід”. Тим самим ви потрапляєте в каталог на рівень вище. Природно, в нашій пошуковій програмі такі елементи не треба вносити в список, тому ми ігноруємо їх знаходження. Виправляємо процедуру натискання на кнопку Button1:

procedure TForm1.Button1Click(Sender: TObject);
Var SR:TSearchRec;
FindRes:Integer;
begin
ListBox1.Clear;
FindRes:=FindFirst(“c:delphi*.*”,faAnyFile,SR);
While FindRes=0 do
begin if ((SR.Attr and faDirectory) = faDirectory) an d / / якщо знайдений елемент каталог і ((SR.Name = “.”) Or (SR.Name = “..”)) then / / він має назву “.” або “..”, тоді:
begin FindRes: = FindNext (SR); / / продовжити пошук Continue; / / продовжити цикл
end;
ListBox1.Items.Add(SR.Name);
FindRes:=FindNext(SR);
end;
FindClose(SR);
end;

В цьому випадку, при знаходженні каталогу з ім’ям “.” або з ім’ям “..” програма продовжить обробку циклу пошуку без виведення знайденого імені елемента в компонент списку ListBox1.

Тепер розглянемо тип TSearchRec. Він має у собі кілька корисних властивостей:



Всі перераховані вище властивості ми вже розглянули або вони зрозумілі відразу, за винятком властивості Time. Воно має тип Integer і містить в собі упаковане значення дати і часу створення файлу. Розпакування проводиться за допомогою функції FileDateToDateTime, яка в результаті повертає значення дати і часу.
Тепер додамо в нашу форму компонент DateTimePicher1 (сторінка Win32) і допишемо кілька рядків.

procedure TForm1.Button1Click(Sender: TObject);
Var SR:TSearchRec;
FindRes:Integer;
begin
ListBox1.Clear;
FindRes:=FindFirst(“c:delphi*.*”,faAnyFile,SR);
While FindRes=0 do
begin
if ((SR.Attr and faDirectory)=faDirectory) and
((SR.Name=”.”)or(SR.Name=”..”)) then
begin
FindRes:=FindNext(SR);
Continue;
end; if FileDateToDateTime (SR.Time)

Як ви вже помітили, ми відбираємо файли і каталоги за датою створення, починаючи з вказаної в компоненті DateTimePicker1.

Тепер спробуємо організувати пошук файлів у всіх вкладених каталогах. Це не так просто, як може здатися на перший погляд. Нам доведеться вручну організовувати весь цикл входу-виходу з каталогу, перебір файлів. Трохи важкувато матеріал, але можливо ті з вас, хто вже працював з мовою програмування pascal або іншим, знайомі з технологією багатократності і многовложенності використання одного і того ж програмного коду. Коротко поясню алгоритм роботи такої програми.



  1. Завдання початкових умов пошуку, пошук першого елемента.

  2. Якщо знайдений файл, то виводимо його і відповідно обробляємо (виводимо в список, відкриваємо, видаляємо і т.п.).

  3. Якщо знайдений каталог, то починаємо нову процедуру пошуку. Але програмний код залишається незмінним. Ми просто заново викликаємо і входимо в цю ж процедуру пошуку.

  4. Обробляємо таким же чином всі вкладені в цей каталог файли і каталоги (починаємо новий пошук у виявленому каталозі).

  5. Якщо елементів у вкладеному каталозі більше немає, то обробка процедури пошуку в ньому завершується, і ми виходимо з неї. При цьому ми опиняємося в тому ж місці, звідки й викликали цю процедуру. Але вона була викликана з цієї ж процедури. Тому програма продовжує своє виконання далі з моменту повернення.

Таким чином, скільки витків програма намотує на так званий клубок, стільки витків вона і розмотати. Програма на виконанні проходить все дерево вкладених каталогів, виконуючи один і той же шматок програмного коду! І при цьому дані умов пошуку не переплутуються, і для кожної унікальної процедури вони зберігаються.


Розглянемо приклад. Створіть новий проект. Для створення окремої процедури пошуку нам потрібно оголосити її у відповідному розділі (створюємо її вручну, тому й самостійно оголошуємо).

У розділі public пишемо рядок:

procedure FindFile(Dir:String);

А в розділі коду програми, до слова “end.” вставляємо порожній каркас процедури

procedure TForm1.FindFile(Dir:String);
begin
end;

На форму вставляємо компонент списку ListBox1, Button1, Edit1. Для компонента Edit1 властивість Text встановлюємо в “c: delphi”. Зверніть увагу на останній символ, знак “”, присутність якого в початковому шляхи пошуку обов’язково. Далі процедура OnClick для кнопки Button1 виглядає наступним чином:

procedure TForm1.Button1Click(Sender: TObject);
begin ListBox1.Clear; / / очищення списку файлів FindFile (Edit1.Text); / / пошук файлів з початковими умовами, заданих в Edit1
end;

Створена нами вручну процедура пошуку:

procedure TForm1.FindFile(Dir:String);
Var SR:TSearchRec;
FindRes:Integer;
begin
FindRes:=FindFirst(Dir+”*.*”,faAnyFile,SR);
While FindRes=0 do
begin
if ((SR.Attr and faDirectory)=faDirectory) and
((SR.Name=”.”)or(SR.Name=”..”)) then
begin
FindRes:=FindNext(SR);
Continue;
end; if ((SR.Attr and faDirectory) = faDirectory) then / / якщо знайдений каталог, то
begin FindFile (Dir + SR.Name + “”); / / входимо в процедуру пошуку з параметрами поточного каталогу + каталог, що ми знайшли FindRes: = FindNext (SR); / / після огляду вкладеного каталогу ми продовжуємо пошук в цьому каталозі Continue; / / продовжити цикл
end;
ListBox1.Items.Add(SR.Name);
FindRes:=FindNext(SR);
end;
FindClose(SR);
end;

Якщо ви в компоненті Edit1 в якості початкової умови пошуку файлів задасте кореневу папку диска, наприклад “С:”, то ви отримаєте повний перелік всіх файлів на даному диску. Зверніть увагу на швидкість пошуку файлів і швидкість роботи вашої програми.


Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*