Лекции.Орг


Поиск:




Категории:

Астрономия
Биология
География
Другие языки
Интернет
Информатика
История
Культура
Литература
Логика
Математика
Медицина
Механика
Охрана труда
Педагогика
Политика
Право
Психология
Религия
Риторика
Социология
Спорт
Строительство
Технология
Транспорт
Физика
Философия
Финансы
Химия
Экология
Экономика
Электроника

 

 

 

 


Файли з довільною виборкою




 

Мета роботи. Вивчити методи проектування файлів з прямим доступом.

 

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

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

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

Обмін програм з файлами проводиться одиницями інформації - логічними записами. Є два основні методи логічного доступу до файлу: послідовний і довільний. При послідовному доступі логічні записи зчитуються і записуются в строгій послідовності один за одним. При довільному доступі читання/запис може здійснюватися у довільний логічний запис, номер якого заздалегідь заданий.

При послідовному доступі найбільш часто в якості логічних записів розглядаються рядки: послідовності байт завершені символами '\r'(повернення каретки) і '\n' (перевод рядка), які мають десяткові коди 13 і 10, відповідно. В логічних записах зберігаються як числа, так і символи. Останні зберігаються по одному байту на символ і кодуються згідно прийнятій системі кодування. Числа зберігаються в символьному вигляді. Так ціле число 128, що займаює в пам'яті два байти (16-е представлення 00 80), розташовується у файлі в виді послідовності з трьох символів '1','2' і '8'. Найбільш характерним представником файлів з послідовним доступом є текстові файли, що використовуються для зберігання програм, документів і даних.

Оскільки всі записи в послідовному файлі мають довільну довжину, то для знаходження потрібного запису програма повинна прочитувати файл спочатку і відлічити потрібну кількість пар символів '\r' і '\n'.

Файли прямого доступу мають логічні записи фіксованої довжини. В цьому випадку легко можна працювати з логічною записом, що має довільний номер. Для цього треба просто обчислити номер байта у файлі, відповідний початковому байту шуканого запису і встановити на нього вказівник запису/зчитування. Кожний запис може містити декілька полів, що мають фіксований розмір. Наприклад, записи файлу, що містить інформацію про пацієнтів деякої лікарні, можуть містити наступні поля: Прізвище, Зріст, Вага, Рік народження тощо. Символи в записах зберігаються по одному байту, а числа зберігаються в тому ж вигляді, як вони представляються в пам'яті.Наприклад, число 128 зберігається у вигляді послідовності двох байт '\x00' і '\x80'. Файли прямого доступу створюються наперед і спочатку містять порожні записи, які заповнюються або змінюються по мірі необхідності. В найпростішому випадку розмір файлу з часом не змінюється.

ОС забезпечує прямий доступ до кожного байту файлу, тобто логічний запис складається з одного байта. Файл зберігається як логічно безперервна послідовність байт. Місце у файлі, з якого починатиметься наступна операція введення/ввиведення, називаєтся вказівником введення/виведення, який зберігається в дескрипторі файлу. Після кожної операції обміну положення вказівника змінюється. Вказівник програмно доступний, тобто можна прочитати його вміст і записати в нього нову позицію для наступної операції обміну. Забезпечення складнішого доступу до файлу покладається на програміста. Розглянемо функції введення-виведення низького рівня.

Функції введення/виведення нижнього рівня не виконують буферизацію і форматування, як це роблять функції обміну інформації з потоками типу fscanf і fprint. Низькорівневі функції можуть розглядатися як безпосереднє звернення до можливостей операційної системи. В роботі використовуються наступні функції: close (закрити файл), lseek (перепозиціювання вказівника файлу в задану позицію), open (відкрити файл), read (читати дані з файлу), write (записати дані у файл). Оголошення для цих функцій розташовані в заголовному файлі io.h.

Перед виконанням операцій з файлом він повинен бути відкритий. Файл може бути відкритий для читання та/або запису в текстовому або двійковому вигляді.

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

Прапори, що використовуються у функціях введення виведення низького рівня, містяться в заголовному файлі fcntl.h. В деяких випадках файли types.h і stat.h також використовуються для роботи з файлами.

Функція open має наступний формат

 

int open (char *pathname, int oflag[, int pmode]),

 

де pathname - ім'я файлу, що відкривається, оflag - режим відкриття. Аргумент oflag є цілим виразом, сформованим комбінацією однієї або більше наступних заголовних констант, визначених в fcntl.h (коли задається більш однієї заголовної константи, вони розділяються операціями АБО (|)):

O_APPEND - перерозташувати вказівник файлу на кінець файлу перед кожною операцією запису;

O_CREAT - створити і відкрити новий файл для запису, не дає результату, якщо файл вже існує;

O_EXCL - функція повертає помилковий код -1, якщо визначений в pathname файл вже існує; Застосовується тільки разом з O_CREAT;

O_RDONLY - відкрити файл тільки для читання; якщо цей прапор був заданий, ні O_RDWR, ні O_WRONLY не можуть бути задані;

O_RDWR - відкрити файл для читання і запису; якщо цей прапор був заданий, ні O_RDONLY, ні O_WRONLY не можуть бути задані;

O_TRUNС - відкрити і звузити існуючий файл до нульової довжини; файл повинен мати доступ для запису. Вміст файлу втрачається;

O_WRONLY - відкрити файл тільки для запису; якщо цей прапор був заданий, ні O_RDONLY, ні O_RDWR не можуть бути задані;

O_TEXT - відкрити файл в текстовому режимі (Комбінація символів повернення-каретки/переведення-рядка (CR/LF) перетворюється у переведення рядка (LF) при введенні; символ LF переводиться в комбінацію CR/LF при виведенні. Символ Ctrl-Z є ознакою кінця файлу.);

O_BINARY - відкрити в двійковому режимі. (Вказані вище переведення забороняються. Символ Ctrl-Z не є ознакою кінця файлу.).

Аргумент pmode потрібен тільки тоді, коли визначений режим відкриття O_CREAT. Якщо файл існує, pmode ігнорується. У іншому випадку pmode визначає спосіб доступу до файлу, що встановлюється після його першого закриття. Pmode є цілий вираз, що містить одну або обидві константи S_IWRITE і S_IREAD, визначених у файлі stat.h. Коли обидві константи задаються, вони розділяються операцією АБО(|). Рmode приймає наступні значення:

S-IWRITE - доступ для запису;

S-IREAD - доступ для читання;

S-IREAD | S-IWRITE - доступ для читання і запису.

Якщо доступ для запису не був заданий, файл відкривається тільки для читання

Функція повертає хендл відкритого файлу і -1 при помилці. При невдалому відкритті системна змінна errno встановлюється в одне з наступних значень:

EACCES - задане ім'я шляху є каталогом, або спроба відкрити для запису файл, який призначений тільки для читанн;

EEXIST - були визначені O_CREAT і O_EXCL прапори, але файл вже існує;

EMFILE - немає більше доступних файлів handle (дуже багато відкритих файлів);

ENOENT -файл або ім'я шляху не знайдено.

Приклад.

 

#include <fcntl.h>

#include <types.h>

#include <stat.h>

#include <io.h>

#include <stdlib.h>

main()

{ int fn1, fn2;

fn1 = open("data1", O_RDONLY);

if (fn1 == -1) реrror("спроба відкрити ввідний файл невдала");

fn2 = open("data2”, O_WRONLY|O_TRUNC|O_CREAT, S_IREAD|S_IWRITE);

if (fn2 == -1) реrror("спроба відкрити вивідний файл невдала");

}

Для виведення повідомлень про помилку використовується функція реrror, яка разом з вказаним в ній текстовим рядком виводить в стандартний потік помилок stderr системне помилкове повідомлення, пов'язане із змінною errno.

Відкриті файли автоматично закриваються, при нормальному завершенні. Для примусового закриття файлів використовується функція int close(int handle), де handle - хендл файлу, що закривається.

Функція повертає 0, якщо файл успішно був закритий, і -1, якщо хендл handle є недійсним аргументом. При невдалому закритті системна змінна errno встановлюється в EBADF - недійсне значення хендла або була спроба записати у файл або пристрій, відкриті тільки для читання.

Приклад.

 

#include <io.h>

#include <fcntl.h>

main()

{ int fh;

fh = open("data",O_RDONLY);

close(fh);}

 

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

 

long lseek(int handle, long offset, int origin)

 

де handle - хендл файлу, а параметр origin визначає як використовується зсув offset для визначення нового положення вказівника:

SEEK_SET - від початку файлу;

SEEK_CUR - від поточної позиції вказівника файлу;

SEEK_END від кінця файлу.

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

При вдалому завершенні функція повертає зсув в байтах нової позиції покажчика від початку файлу. При помилці повертається -1L, при цьому системна змінна errno встановлюється в одне з наступних значень:

EBADF- (див. вище)

EINVAL - недійсне значення для origin, або позиція, щовизначається зсувом offset, вказує на дані, розташовані до початку файлу.

Приклад.

 

#include <io.h>

#include <fcntl.h>

#include <stdlib.h>

main()

{ int fh; long роsition;

fh = open("data", O_RDONLY);

роsition = lseek (fh, 0L, SEEK_SET);

if (роsition == -1L) реrror("переміщення на початок невдале");

/* знайти поточну позицію */

роsition = lseek (fh, 0L, SEEK_CUR);

if (роsition == -1L) реrror ("переміщення на поточну позицію невдале");

роsition = lseek(fh, 0L,SEEK_END);

if (роsition == -1L) реrror("переміщення на кінець невдале");}

 

Для читання і запису даних застосовуються функції read і write. Ці операції починають свої дії з поточної позиції покажчика у файлі, яка змінюється при кожній операції читання або запису. Для запису інформації використовується функція write, яка має наступний формат:

 

int write(int handle, char *buffer, unsigned count),

 

де handle - хендл файлу, куди буде записано count байтів інформації з буфера buffer.

Після операції запису вказівник збільщується на число записаних байт. Якщо файл був відкритий для додавання (APPEND), операція починається з кінця файлу.

Функція повертає число дійсно записаних байт. Значення, що повертається, може бути додатним, але менше count. Повернення числа -1 свідчить про помилку, при цьому змінна error встановлюється в одне з наступних значень:

EACCES - файл захищений від запису;

EBADF - недійсний хендл;

ENOSPC - недостатньо дискової пам'яті.

Приклад.

 

#include <io.h>

#include <stdio.h>

#include <fcntl.h>

char buffer[30000];

main()

{ int fh; unsigned nbytes = 30000;

int byteswritten;

if ((fh = open("с:/data/cont.dat",O_WRONLY)) == -1) {

реrror("невдала спроба відкрити вивідний файл");

exit(1); }

if ((byteswritten = write(fh, buffer, nbytes)) == -1){

реrror("Помилка запису");

else printf("Записано %d байтов\n", byteswritten);

}

Функція read застосовується для читання інформації з файлу і має формат:

 

int read (int handle, char * buffer, unsigned count);

 

де handle - хендл файлу, з якого ця функція намагається прочитати count байтів в буфер buffer. Операція читання починається з поточної позиції вказівника. Після читання вказівник файлу вказує на наступний непрочитаний символ.

Функція повертає число дійсно прочитаних символів, яке може бути менше ніж count, якщо у файлі залишалось недостатнє число байт. Якщо файл був відкритий в текстовому вигляді, значення, що повертається, може не відповідати числу дійсно прочитаних байтів. Це пояснюється тим, що кожна комбінація поверення-каретки/новий_рядок (LF) замінюється символом нового рядка (LF), і лише символ нового рядка зараховується в значення, що повертається.

При спробі прочитати за кінцем файлу повертається 0. При помилці повертається число -1 і системна змінна errno приймає значення: EBADF (Див. вище)

Приклад

 

#include <io.h>

#include <stdio.h>

#include <fcntl.h>

char buffer [60000];

main ()

{int fh;

unsigned int nbytes = 60000, bytesread;

if ((fh = open ("conf.dat", O_RDONLY)) == -1) {

реrror ("спроба відкрити ввідний файл невдала");

exit (1); }

if ((bytesread = read (fh, buffer, nbytes)) == -1) реrror (" ");

else printf ("прочитано %u байтів з файла\n", bytesread);

}

При написанні системи управління прямим доступом до файлу нам знадобиться функція

 

int chsize(int handle, long size),

 

яка розширює або звужує файл, зв'язаний з хендлом handle до довжини, визначеної в size. Файл повинен бути відкритий з доступом для запису. Якщо файл розширяється, він заповнюється нульовими символами.

При успішній зміні довжини функція повертає 0, при помилці -1 і змінна errno встановлюється в одне з наступних значень:

EACCES - вказаний файл тільки для читання.;

EBADF - (див. вище).

ENOSPC - недостатньо місця на диску.

Приклад.

 

#include <io.h>

#include <fcntl.h>

#include <types.h>

#include <stat.h>

#define SIZE 32768L

main()

{int fn, result;

fn = open("data", O_RDWR|O_CREAT, S_IREAD|S_IWRITE);

result = chsize (fn, SIZE); }

 

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

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

Для визначеності припустимо, що файл містить інформацію про членів деякого колективу і кожний логічний запис має два поля: Прізвище - 14 символів і рік народження - цілий тип int -2 байта. Сумарна довжина запису rcrdsz =16 байт.

Зблокуємо записи в блоки по 512 байт. В 0-й блок входять 0-а, 1-а... 31-а записи. В 1-й блок входять 32-а, 33-а... 63-а записи тощо. Обмін інформацією з диском проводитимемо блоками, тобто розмір буфера рівний розміру блоку і рівний 512 байт.

Нехай Ваша програма працює з i- м записом. Він знаходиться в блоці bl=i*rcrdsz/512 (цілочисельне ділення) і починається в цьому блоці з байта n=i*rcrdsz%512. Якщо була задана адреса buf початку буфера обміну, в якому розташований bl -й блок, то k=buf+n указує на початок i-го запису файлу в буфері buf. Тут k і buf мають тип char*.

Логічний запис доцільно розглядати як структуру. В нашому випадку вона має вигляд:

struct _rec {char name[14]; /* Прізвище */

int gr;}; /* Рік народження*/

 

Структура _rec визначає вміст логічного запису з точки зору програміста. На диску вона зберігається у вигляді послідовності 16-ти, що не відрізняються між собою, байт, тобто логічний запис може бути розглянутий з цих двох точок зору. Відповідною структурою даних, що відображає цю неоднозначність, є об’єднання union. В нашому випадку можна рекомендувати наступну конструкцію:

 

union _bufrec {char bufrec[16];

struct _rec rec;} rbuf;

 

Тоді rbuf,bufres - це послідовність з 16-ти байт, яка є логічним записом rbuf.rec, що складається з двох полів rbuf.rec.name (прізвище) і rbuf.rec.gr (рік народження). Або в іншому трактуванні: вміст полів rbuf.rec.name і rbuf.rec.gr логічного запису rbuf.rec можуть бути розглянуті як послідовність з 16-ти байт rbuf.bufrec.

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

 

typedef struct afile {

char *buf; /* Буфер обміну*/

int bz; /*Номер блоку, завантаженого в буфер обміну, спочатку -1*/

int w; /*Якщо в buf був виконаний запис, то w=1 інакше w=0*/

int rcrdsz; /* Довжина логічного запису*/

int numrec; /* Кількість логічних записів у файле*/

int handler; /* Хендл файлу*/}

AFILE;

 

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

При роботі з i-им логічним записом необхідно обчислити номер відповідного блоку bl=i*rcrdsz/512 (цілочисельне ділення) і визначити початок запису в цьому блоці n=i*rcrdsz%512. Потім слід перевірити чи не знаходиться логічний запис в буфері (bl==ap->bz). Якщо ні, то дивимося чи змінювався вміст буфера (ap->w==1). Якщо змінювався, тоді слід скинути буфер на диск в ap->bz -й блок, тобто записати вміст буфера ap->buf у файл починаючи з ap->bz*512 -го байта. Далі (при bl!=ap->bz) слід записати в буфер ap->buf bl -й блок файлу, тобто ввести в буфер з файлу 512 байт, починаючи з 512* bl -й позиції, встановити новий номер завантаженого в буфер блоку ap->bz=bl і скинути прапорець зміни буфера ap->w=0. Після цього необхідний логічний запис буде знаходитися в буфері, починаючи з n -го байту.

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

 

Практична частина.

 

1. Вивчити теоретичну частину. Вміти відповідати на контрольні питання.

2. Для організації системи прямого доступу до файлу слід pозpобити наступні функції:

2.1. Функція створення файлу прямого доступу

 

int асreate (char* name, int rcrdsz, int numrec),

 

де name - ім'я створюваного файлу, rcrdsz - розмір логічного запису в байтах, numrec - кількість логічних записів у файлі.

Функцію слід організувати таким чином.

За допомогою функції open перевіряється існування файлу з ім'ям name. Якщо файл є на диску, функція асreate повертає -1.

Використовуючи функцію open, створюємо бінарний файл name з доступом для запису і читання.

Застосовуючи 2 рази функцію write, записуємо в перші 4 байта файлу розмір логічного запису в байтах і кількість логічних записів.

Змінимо розмір створеного файлу до величини 4+rcrdsz*numrec (функція chsize).

Закриємо файл (функція close).

2.2. Функція для відкриття створеного файлу прямого доступу

 

AFILE *aopen(char *name),

 

де name - ім'я файлу.

Алгоритм роботи, що рекомендується.

Зарезервувати пам'ять для структури AFILE

 

AFILE *ap=(AFILE*)malloc(sizeof(AFILE)).

 

Заповнити поля структури, для чого:

- виділити 512 байт для буфера обміну ap->buf=(char*)malloc(512);

- відкрити за допомогою функції open двійковий файл name з доступом для запису і читання і присвоїти отриманий хендл полю структури ap->handler;

- використовуючи двічі функцію read прочитати з файлу розмір логічного запису і кількість логічних записів у файлі, заповнивши поля ap->rcrdsz і ap->numrec;

- встановити ознаку зміни буфера обміну ap->w в 0;

- присвоїти полю ap->bz -1.

Повернути в програму вказівник ар на структуру AFILE.

2.3. Функція для обміну інформацією між програмою користувача і файлом прямого доступу

 

int areadwrite(AFILE *ap,int nr, char* rec, int mode),

 

де ар - вказівник на структуру, що описує файл прямого доступу, з яким ведеться робота, nr - номер логічного запису у файлі, з яким проводиться обмін інформацією, rec – буфер користувача, рівний за розміром довжині логічного запису і що використовується для введення-виведення записів, mode - режим обміну (0 - читання, 1 - запис).

Функція повинна виконувати наступні дії.

Обчислити номер блоку bl=nr*rcrdsz/512, в якому розташований логічний запис з номером nr і початок запису в цьому блоці n= nr *rcrdsz%512.

Перевірити чи не знаходиться логічний запис nr в буфері (bl==ap->bz). Якщо ні, то дивимося чи змінювався вміст буфера (ap->w==1). Якщо змінювалося, то слід скинути буфер на диск в ap->bz -й блок, тобто, використовуючи функції lseek і write, записати вміст буфера ap->buf у файл починаючи з 4+ap->bz* 512-го байта. Далі (при bl!=ap->bz) слід:

- записати в буфер ар ->buf bl- й блок файлу, тобто застосовуючи функції lseek і read, ввести в буфер з файлу 512 байт, починаючи з 4+512*bl -ї позиції;

- встановити новий номер ap->bz=bl завантаженого в буфер блоку;

- скинути прапорець зміни буфера ap->w =0. Логічний запис nr знаходиться в буфері ap->buf, починаючи з n -го байта і з ним можна вести обмін інформацією залежно від значення змінної mode;

- при читанні (mode=0), дані переписуються з буфера обміну в призначений для користувача буфер:

 

for(i=0;i<rcrdsz;i++)rec[i]=(ap->buf+n)[i].

 

- при запису (mode=1) проводиться обмін інформацією в зворотньому напрямі:

for(i=0;i<rcrdsz;i++)(ap->buf+n)[i]=rec[i]

 

і встановлюється ознака зміни вмісту буфера обміну ap->w=1.

 

2.4. Функція закриття файлу прямого доступу

 

int асlose(AFILE *ap),

 

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

Функція працює таким чином.

Якщо вміст буфера ap->buf змінювався (ap->w==1), то слід встановити вказівник запису-читання на початок завантаженого блоку (4+ap->bz*512) і записати буфер на диск. Хендл файлу знаходиться в ap->handler.

За допомогою функції free слід послідовно звільнити пам'ять, що зайнята буфером ap->buf, закрити файл з хендлом ap->handler і звільнити пам'ять від структури AFILE, на яку вказує змінна ар.

3. Для перевірки правильності роботи системи прямого доступу до файлу слід використовувати наступну функцію main

 

typedef struct afile {

char *buf;

int bz;

int w;

int rcrdsz;

int numrec;

int handler;} AFILE;

#include <stdio.h>

#include <io.h>

#include <fcntl.h>

#include <stat.h>

#define R 0

#define W 1

struct _rec {char name[14]; int gr;};

int асreate (char*, int, int); /*Прототипи */

AFILE *aopen(char *) *ap;

int areadwrite(AFILE*, int, char*, int);

int асlose(AFILE *ap); /* функцій */

main()

{ int i, nr;

char s[13],c,c1;

union _bufrec {char bufrec[16]; /*Буфер*/

struct _rec rec;} rbuf; /* rористувача */

printf("\nВведіть ім'я нового файлу прямого доступа\

(100 записів по 16 байт): ");

gets(s);

if(-1==acreate(s,16,100))

printf("\nЧи будете працювати з існуючим файлом %s!",s);

ap=aopen(s); /* Відкриття файлу прямого доступа*/

do { /* Основний цикл*/

for(i=0;i<16;i++)rbuf.bufrec[i]='\0'; /* Обнулення логічного запису*/

puts("\nHомеp запису?");

scanf("%d",&nr);

areadwrite(ар, nr, rbuf.bufrec, R); /* Читання логічного запису */

/* Виведення запису на экран*/

printf("\nЗапис #%d. Вміст полів:\n Ім’я=\" %s\". \

Рік народження = %d",nr,rbuf.rec.name,rbuf.rec.gr);

puts(" \nЧи будете змінювати/формувати запис (у/n)?");

c=getche();

if(c=='y')

{puts("\nПрізвище?"); /*Введення полів логічного запису з клавіатури*/

scanf("%s",rbuf.rec.name);

puts("\nРік народження?");

scanf("%d",&rbuf.rec.gr);

areadwrite(ар, nr, rbuf.bufrec, W); /* Запис логичного запису на диск */

}

puts("\nЧи будете працювати з файлом ще (у/n)?");

c1=getche();

}

while(c1=='y');

асlose(ар); /* Закриття файла*/

}

Зверніть увагу на використовування змінної типу об’єднання rbuf.

 

Контрольні питання.

 

1. Що таке дескриптор файлу і його хендл?

2. В чому полягає процес відкриття файлу?

3. Що таке логічний запис?

4. Охарактеризуйте послідовний доступ до файлу.

5. В чому суть довільного доступу до файлу?

6. Який режим доступу до файлів забезпечують системи UNIX і MS DOS?

7. Яку роль в організації файлових систем відіграє вказівник запису/читання?

8. Які функції дозволяють відкривати і закривати файли?

9. Яка функція і як забезпечує установку позиції запису/читання у файлі?

10. Як прочитати (записати) інформацію в (з) файл(а)?

11. Чи можна змінювати розмір існуючого файлу?

12. Навіщо застосовують буферизацію при роботі з файлами?

13. Висловити алгоритм буферизації.

14. Привести алгоритм організації прямого доступу до файлу.

15. Навести приклади форматів логічних записів.

16. Які типи даних рекомендується застосовувати при роботі з логічними записами?

17. Який виграш дає робота вживання структури AFILE з файлами прямого доступу?

18. Яку інформацію і навіщо рекомендується додавати в початок файлу прямого доступу?

Лабораторна робота №6.





Поделиться с друзьями:


Дата добавления: 2016-09-06; Мы поможем в написании ваших работ!; просмотров: 365 | Нарушение авторских прав


Поиск на сайте:

Лучшие изречения:

Лаской почти всегда добьешься больше, чем грубой силой. © Неизвестно
==> читать все изречения...

2419 - | 2290 -


© 2015-2025 lektsii.org - Контакты - Последнее добавление

Ген: 0.015 с.