Реферат: Фізичні файли та файлові змінні
Значення саме цього елемента буде читатися за виконання виклику процедури введення read чи цьому елементу буде щось присвоюватися за виконання write. В обох випадках доступним стане наступний елемент:
f0 | f1 | f2 | f3 | ... | fN |
Підкреслимо, що виклик процедури Seek записується після відкривання файла за допомогою reset, і після нього можна як читати, так і записувати елементи файла, тобто режим доступу не має значення.
У системі Турбо Паскаль є також кілька допоміжних процедур, що застосовуються разом із процедурою Seek.
Функція FILEPOS задає повернення номера доступного елемента. Єдиним аргументом у її виклику є ідентифікатор файлової змінної, а повертається значення типу LongInt. Наприклад, за останнього зображеного значення файлової змінної f присвоювання
A := FilePos ( f );
надає змінній А типу LongInt значення 3.
Для визначення загальної кількості елементів у файлі використовують функцію FILESIZE. Її единим параметром є ідентифікатор файлової змінної, і з її виклику повертається значення типу LongInt. Наприклад, значенням змінної N типу LongInt після присвоювання
N := FileSize ( f )
стає кількість елементів у файлі.
Зрозуміло, що використовуючи у програмі виклик процедури seek в парі з викликами read або write, ми зможемо прочитати будь-який елемент файла чи зробити заміну його значення.
Зокрема, за допомогою процедур seek, filesize і write можна розширити файл, дописуючи значення нового елемента в кінець:
seek ( f, filesize ( f ));
write ( f, v ).
Дійсно, після виклику seek файловий вказівник встановлюється за останнім елементом, тобто
f0 | f1 | f2 | ... | fN |
а після виклику write значення v записується в новий елемент, після чого файловий вказівник переміщається вправо:
f0 | f1 | f2 | ... | fN | fN+1 |
Процедура TRUNCATE задає знищення решти файла, починаючи від доступного елемента. Наприклад, після виконання викликів
seek(f, 3); truncate(f)
елементи з 3-го по останній знищуються, а залишаються з номерами 0, 1 і 2.
Використання процедур прямого доступу дозволяє вилучати елементи з файла.
Приклад 4. Наведемо програму, яка задає вилучення непотрібних елементів файла, тобто його стискання.
Нехай у файлі Group.dat зберігається інформація про студентів групи: прізвище, ім’я та середній бал. З клавіатури задається прізвище студента, який вибув – запис про нього треба вилучити з файла.
За наступною програмою файл читається до кінця і в допоміжний файл копіюються ті записи, поле-прізвище яких відрізняється від заданого. Далі файли закриваються, і засобами модуля System старий файл просто знищується, а допоміжному присвоюється зовнішнє ім’ я старого.
program OutFromGroup;
type Student = record
Sname, Name : string[20];
Ball : real;
end;
var Fi, Fo : file of Student; { інформаційний та допоміжний файл }
FileName: string; { ім’ я файла }
procedure OpenFile;
begin
writeln('Задайте ім''я файла'); readln(FileName);
assign(Fi, FileName); reset(Fi);
assign(Fo, 'NewFile.dat'); rewrite(Fo);
end;
procedure ClearFile; { Процедура стискання файла }
var St : Student; { Змінна для обміну }
StudtoOut : string[20];
begin
writeln('Задайте прізвище студента, що вилучається:');
readln(StudtoOut);
while not eof(Fi) do
begin
read(Fi, St);
if St.SName <> StudtoOut then
write(Fo, St)
end;
close(Fi);
close(Fo);
{Виклики процедур модуля System }
Erase(Fi); {для знищення}
ReName(Fo, FileName); {та переіменування файла }
end;
begin
OpenFile;
ClearFile;
end.
Крім операцій заміни та вилучення елементів файла, опишемо операцію вставки елемента в довільне місце файла. Нехай місце задається номером нового елемента в файлі. Для вставки використовують один із двох алгоритмів.
У першому алгоритмі використовується допоміжний файл, в який переписуються всі елементи, що передують заданому.
Відкрити основний та допоміжний файли.
У циклі переписати з основного файла в допоміжний всі елементи, номери яких менші заданого. Для цього можна використати допоміжну змінну того ж типу, що і в елементів файла.
У допоміжний файл записати значення, яке треба вставити.
У циклі переписати з основного файла в допоміжний усі елементи, що залишились.
Закрити основний та допоміжний файли.
Знищити основний файл.
Переіменувати допоміжний файл в основний.
У другому алгоритмі замість допоміжного файла використовуються дві допоміжні змінні того ж типу, що і в елементів файла, та допоміжна змінна-лічильник типу LongInt для запам’ятовування поточного місця вставки.
Першій допоміжній змінній присвоїти значення, яке треба вставити в файл.
Встановити файловий вказівник на місце вставки за допомогою процедури Seek.
Запам’ятати місце вставки в змінній-лічильнику за допомогою функції FilePos.
Прочитати значення того елемента, на який вказує файловий вказівник, і присвоїти другій допоміжній змінній.
Знов установити файловий вказівник на місце вставки за допомогою процедури Seek, використавши значення лічильника.
В циклі, поки файл не прочитано:
записати в доступний елемент файла значення з першої змінної;
запам’ятати нове місце вставки, збільшивши лічильник;
першій допоміжній змінній присвоїти значення другої;
прочитати значення того елемента, на який вказує файловий вказівник, і присвоїти другій допоміжній змінній;
установити файловий вказівник на місце вставки за допомогою процедури Seek, використавши значення лічильника.
Записати в доступний елемент файла значення з першої змінної.
Наостанок зауважимо, що значення другого аргументу у виклику процедури Seek може не бути номером елемента в файлі, тобто може бути від’ ємним або більшим кількості елементів файла. За її виклику нічого не трапиться, але за подальшої спроби читати елемент із установленим номером виконання програми аварійно завершиться. Адже елемента з таким номером немає!
Ще цікавіше буде, якщо у виклику Seek задати номер, більший від кількості елементів у файлі, а потім спробувати записати в цей ніби доступний елемент файла. Все буде гаразд, але після цього в файлі чомусь з’ явиться зовсім незрозуміла інформація, "сміття". Перевірте цю інформацію та поміркуйте, звідки береться "сміття"! І будьте уважні, коли записуєте другий аргумент процедури Seek.
Задачі
8. Написати "дурнестійкий" варіант процедури Seek, за яким не дозволяється задавати від’ ємний чи більший від кількості елементів файла номер елемента. Зауважимо, що варіант такої процедури для подальшого читання відрізняється від варіанта для запису тим, що при читанні найбільшим номером доступного елемента є Filesize(f)-1, а при записі – Filesize(f).
9. Написати програми, що реалізують алгоритми вставки нового значення в файл.
10. Написати програму вилучення елемента з файла даних про студентів групи, аналогічну програмі з прикладу 13.4, в якій не використовується допоміжний файл (доцільно застосувати процедуру Truncate).
11. Написати процедуру вилучення з файла елемента за його номером.