НОУ ІНТУІТ, Лекція, Робота з текстовими файлами
Загальні принципи роботи з файлами
У попередніх прикладах ми зберігали текст у файл і зчитували текст із файлу за допомогою властивостей:
Цей метод зручний і хороший, проте він не дозволяє нам контролювати весь процес запису у файл та читання з файлу. Тобто ці функції весь процес читання та запису виконують приховано від нас.
Однак буває, коли програміст відчуває необхідність контролю цих процесів, крім того, не всім типів ці функції доступні. Наприклад, у нас є текст у рядковій змінній. Ми вже говорили, що рядкова змінна може зберігати майже необмежену кількість символів, тобто змінну ми можемо записати весь текстовий файл , включаючи і символи переходу на інший рядок і повернення каретки (#13 #10). З функціями SaveToFile() і LoadFromFile() можуть працювати дані, які мають тип TStrings , а прості рядки не можуть викликати їх. Тому доводиться робити записи у файл безпосередньо, і також їх зчитувати.
Для роботи з файлами багато програмістів вважають за краще використовувати функції WinAPI. Незважаючи на грізне звучання, нічого особливо складного в цих функціях немає, проте такі функції мають один великий недолік. Корпорація MicroSoft постійно вносить якісь зміни до своїх операційних систем. Так, у перших версіях Windows для читання файлів використовувалася функція WinAPI _lread . Потім з'явилася функція ReadFile і Microsoft почала рекомендувати використовувати у програмуванні саме її. А потім з'явилася функція ReadFileEx, яка дозволяє працювати з файлами великих розмірів. Після кожної зміни цих функцій часто доводиться переробляти всю програму, щоб вона могла працювати з новою операційною системою. А це забирає багато часу та створюєдодаткові незручності і програмістів, і користувачів.
Тому Delphi рекомендується використовувати вбудований спеціалізований об'єкт TFileStream . Якщо Microsoft запровадить якісь новації, Borland врахує їх в об'єкті, і нам залишиться лише перекомпілювати нашу програму, не змінюючи її коду. Крім того, використання TFileStream набагато простіше, ніж функції WinAPI. TFileStream - це об'єкт, і як кожен об'єкт, його потрібно спочатку оголосити, а потім проініціалізувати.
Насамперед необхідно створити змінну типу TFileStream:
Таким чином, ми оголосили змінну типу об'єкта TFileStream , і надалі можемо працювати з цією змінною, як з об'єктом. Тобто вказувати ім'я цієї змінної, а після точки вибирати властивості, методи та події цього об'єкта. Однак оголосити змінну мало, потрібно ще проініціалізувати її.
Метод Create об'єкта TFileStream може мати три параметри, причому третій параметр необов'язковий, його можна не вказувати. Розберемося із цими параметрами.
Режим відкриття. Тут можна вказати один із таких параметрів:
- fmCreate – Створити файл із вказаним у першому параметрі ім'ям. Якщо файл уже існує, він відкриється в режимі запису.
- fmOpenRead – Відкрити файл лише для читання. Якщо файл не існує, виникне помилка, тому спочатку потрібно виконати перевірку на існування файлу. Неможливо записувати файл у цьому режимі.
- fmOpenWrite – Відкрити файл для запису. При цьому поточний вміст файлу знищується, а файл перезаписується.
- fmOpenReadWrite – Відкрити файл для редагування, тобто і читання, і запису.
Права, з якими буде відкрито файл. Цей параметр є необов'язковим, його можна не вказувати. Він має такіможливі значення:
- fmShareCompat – Інші програми також мають право працювати з відкритим файлом.
- fmShareExclusive – Інші програми не можуть відкрити файл.
- fmShareDenyWrite – Інші програми зможуть відкрити файл лише для читання, записати в нього дані вони не зможуть.
- fmShareDenyRead – Інші програми зможуть відкрити файл тільки для запису, для читання вони не зможуть його відкрити.
- fmShareDenyNone – не заважати іншим програмам працювати з файлом.
Те саме може статися, якщо ваша програма виконана в мережевому варіанті. Наприклад, є якийсь спеціальний файл, у якому співробітники відділу записують свої зміни. Цей файл може перебувати на якомусь мережному диску, і доступ до цього файлу має кожен співробітник. І у кожного співробітника встановлена ваша програма. Таким чином, якщо одночасно двоє співробітників будуть робити зміни у файлі, то дані одного з них загубляться, оскільки програма іншого перезапише файл без урахування цих змін. Якщо ви пишете однокористувацьку програму, і доступ до файлу матиме тільки вона, то про третій параметр можете зовсім забути.
Після того, як Ви створили об'єкт, проініціалізували його і попрацювали з ним, файл потрібно закрити та звільнити пам'ять, яку займає цей об'єкт. Для цього достатньо викликати метод:
Тепер залишилося розібратися зі структурою файлу, та методами читання з нього, та запису до нього. Почнемо зі структури.
Коли ви відкрили файл , позиція курсора встановлюється на початок, і будь-яка спроба читання або запису буде застосована до цієї позиції курсора. Щоб прочитати (записати) в іншу позицію, потрібно пересунути курсор . Для цього використовують метод Seek, який має два параметри:
- Число,вказує кількість байт (символів), куди потрібно пересунути курсор.
- Звідки треба рухатись. Тут може бути три варіанти:
- SoFromBeginning – рухатись на вказану кількість байт від початку файлу.
- SoFromCurrent – рухатись від поточної позиції курсору.
- SoFromEnd - рухатися на вказану кількість байт від кінця файлу до його початку.
Отже, щоб пересунути курсор від початку файлу на 10 байт потрібно виконати команду:
Метод Seek - це функція, вона завжди повертає кількість байт усунення від початку файлу. Цією властивістю можна скористатися, щоб дізнатися загальну кількість байт у файлі:
Правда, якщо нам потрібно просто подивитися розмір файлу, то цей трюк не зовсім підходящий: нам доведеться відкрити файл, переміститися в його кінець, а потім закрити його. Як дізнатися розмір файлу більш відповідним способом, дізнаємось пізніше.
Для читання з файлу потрібно використовувати метод Read , який теж має два параметри:
Розберемо приклад читання з файлу 10 символів, починаючи з 15 позиції:
- Під час читання було досягнуто кінця файлу, і функція прочитала менше байт, ніж планувалося.
- Помилка на диску чи будь-яка інша проблема.
Для запису у файл використовується метод Write. Є два параметри і має:
- Змінна, вміст якої потрібно записати.
- Число байт для запису.
Користуватися методом запису можна так само, як і методом читання.
У наступній лекції ми продовжимо вивчення роботи з файлами.