Нетипізовані файли

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

Ці файли на відміну вже розглянутих немає суворо певного типу.

Нетипізований файл розглядається у Паскалі як сукупність символів чи байтів. Подання char або byte не відіграє ніякої ролі, важливий лише обсяг даних, що займаються.

Для визначення програми нетипізованого файлу служить зарезервоване слово file:

Var MyFile: file;

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

Нетипізований файл є файлом прямого доступу, що говорить про можливість одночасного використання операцій читання та запису.

Для таких файлів найважливішим параметром є довжина запису в байтах. Відкриття нетипізованого файлу з довжиною запису 1 байт можна виконатинаступним чином:

rewrite(MyFile, 1)абоreset(MyFile, 1)

Другий параметр, призначений лише для використання з нетипізованими файлами, визначає довжину запису файлу на сеанс роботи.

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

rewrite(MyFile)абоreset(MyFile)

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

Турбо Паскаль не накладає жодних обмежень на довжину запису нетипізованого файлу, за винятком вимоги позитивності та обмеження максимальної довжини 65535 байт (ємність цілого типу word). При цьому слід враховувати дві обставини.

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

З іншого боку, слід пам'ятати, що загальний розмір файлу може бути кратен вибраному розміру запису (останній запис може бути неповним). Для того, щоб гарантовано забезпечити повне читання всього файлу,рекомендується встановити розмір запису 1.

При роботі з нетипізованими файлами можуть застосовуватися всі процедури та функції, доступні для типизованих файлів. Нагадаємо ці процедури та функції.

assign (Му File,'з:\МуDirectory\result.dat') - процедура зв'язування логічної файлової змінної МуFilе з конкретним фізичним файлом на дисковому носії інформації;

closе (МуFilе) - процедура, що закриває відкритий файл;

rewrite (МуFilе) - процедура, що створює новий файл і відкриває його для запису чи читання; ця процедура має додатковий параметр під час роботи з нетипізованими файлами, який буде розглянуто пізніше;

reset (МуFilе) – процедура, що відкриває існуючий файл даних; ця процедура має додатковий параметр під час роботи з нетипізованими файлами, який буде розглянуто пізніше;

eof (МуFilе) - логічна функція, що перевіряє, чи досягнуто кінець файлу;

seek (МуFilе, n) - процедура, що дозволяє явно змінити значення поточного покажчика файлу, встановивши його елемент з номером n;

filesize(МуFilе) - функція, що повертає позицію покажчика щодо файлу; нумерація починається із нуля;

filepos (МуFilе) - функція, що повертає кількість елементів файлу;

rename (Му File, FileName) - процедура, що дозволяє перейменувати існуючий файл;

truncate(МуFilе) - процедура, що дозволяє видалити частину існуючого файлу, починаючи з поточної позиції;

erase(МуFilе) - процедура, що стирає зазначений файл,

Ви повинні були помітити, що у списку немає процедур read та write. Для читання інформації з нетипізованого файлу та запису інформації в нього тільки для даного типу файлів Турбо Паскаль введено дві нові процедури, що підтримують операції введення-виведення з вищою швидкістю.

Процедура BlockRead

blockread(Var F: file; Var Buf; Kolblocks: word; result: word);

Процедура зчитує з файлу F певну кількість блоків на згадку, починаючиз першого байта змінної Buf.

Параметр Buf представляє будь-яку змінну, яка братиме участь в обміні даними з дисками. Цю змінну потрібно описати в програмі так, щоб її розмір не був меншим за розмір запису, встановлений у параметрах rewrite або reset (як правило, для цих цілей використовується деякий масив).

Параметр result є необов'язковим і містить після виклику процедури число лічених записів.

Використання параметра result підказує, що кількість лічених блоків може бути меншою, ніж задано параметром Kolblocks. Якщо result вказано під час виклику, то помилки введення-виводу в такій ситуації не станеться. Для відстеження цієї та інших помилок читання можна використовувати опції , і функцію IOresult.

Крім того, що змінна F повинна бути описана як нетипізований файл, вона повинна бути пов'язана з конкретним диском фізичним процедурою assign. Файл має бути відкрито процедурою reset.

Процедура BlockWrite

blockwrite(Var F: file; Var Buf; Kolblocks: word; result: word);

Процедура призначена для швидкої передачі файл F певної кількості записів зі змінної Buf. Усі параметри процедури blockwrite аналогічні параметрам процедури blockread. Різниця лише в тому, що файл має бути підготовлений для запису процедурою rewrite. Вміст змінної Buf повністю міститься у файл, починаючи з поточного запису.

Обидві процедури виконують операції введення-виведення блоками. Об'єм блоку в байтах визначається за такою формулою:

Об'єм = Kolblocks * recSize,

де recSize – розмір запису файлу, заданий при його відкритті. Сумарний обсяг разового обміну має перевищувати 64 Кбайт. Крім швидкості передачі даних перевага цих процедурполягає у можливості користувача самостійно визначати розмір буфера для файлових операцій. Ця можливість грає значну роль тих завданнях, де необхідне жорстке планування ресурсів. Програміст повинен подбати про те, щоб довжина внутрішнього подання змінної Buf була достатньою для розміщення всіх байт під час читання інформації з диска.

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

Якщо під час читання вказано змінну Buf недостатньої довжини або якщо в процесі запису на диск не виявиться потрібного вільного простору, то відбудеться таке. Якщо останній параметр result у цих викликах не заданий, виникає помилка вводу-вывода; якщо параметр result заданий, то помилка не буде зафіксована, а після виконання процедури його значення не співпадатиме зі значенням параметра Kolblocks. Останню обставину можна перевірити, порівнявши два зазначені значення.

Після завершення процедури покажчик зміщується на результат записів.

Розгляньте приклади найпростіших завдань.

Завдання 1. Скласти програму, яка створює нетипізований файл зі 100 чисел і виводить на екран k-ий елемент.

Program Netipiz1; Uses Crt; Type FileType = file; Var f : FileType; P, B, k: byte; Begin ClrScr; assign(F, 'MyFile'); rewrite(F,1); Randomize; for k := 1 to 100 do begin P := Random(100); blockwrite(F, P, 1); end; close(F); reset(F,1); for k := 1 to 100 do begin blockread(F, P, 1); write(p,''); end; write('Введіть номер потрібного елемента'); readln(k); Seek(F, k-1); blockread(F, P, 1); writeln(k,'-ий елемент файлу дорівнює ', P); close(F); End.

Завдання 2. Скласти програму, яка створює копію елементів нетипізованого файлу f і поміщає файл g.

Program Netipiz2; Uses Crt; Var f, g: file; Stroka1, sб Stroka2 : string; Begin ClrScr; write('Введіть ім'я вихідного файлу'); read(Stroka1); assign(f, Stroka1); rewrite(f,1); write('Введіть вміст файлу'); repeat readln(s); blockwrite(f, s, 1); until readKey = #27; close(f); reset(f,1); write('Введіть ім'я кінцевого файлу'); read(Stroka2); assign(g, Stroka2); rewrite(g,1); while not Eof(f) do begin blockread(f, s, 1); blockwrite(g, s, 1); end; close(f); close(g); write('Вміст кінцевого файлу:'); while not Eof(g) do begin blockread(g, s, 1); write(s); end; readln; End.

Завдання 3. Скласти програму, яка створює масив цілих чисел і записує їх у нетипізований файл, а також обчислює середнє арифметичне елементів файлу.

Program Netipiz3; Uses Crt; Var f:file; i, k, s: integer; Mas: Array [1..10] of byte; Begin ClrScr; Randomize; for i := 1 to 10 do Mas[i] := Random(10); assign(f, 'file.dat'); rewrite(f,1); blockwrite(f, Mas, 10); close(f); reset(f,1); while not Eof(f) do begin blockread(f, k, 1); s:= s+k; Inc(i); end; close(f); write(s/i:5:2); readln; End.