1. Прямий доступ до даних у файлах.Операції читання даних з файлу і їх запис у файл відбувається, починаючи з поточної позиції в потоці. Початкова позиція встановлюється при відкритті файлу й може відповідати початковому або кінцевому байту потоку залежно від режиму відкриття файлу.
З кожним відкритим файлом асоціюється вказівник позиції, який являє собою системний об’єкт, що вказує місце в файлі, в якому в даний момент виконується операція вводу-виводу. Позиція вказується в байтах від початку файлу. При відкритті файлу вказівник встановлюється на початок файлу і рівний 0, так як файл має довжину 0 і інших позицій в ньому бути не може.
При відкритті потоку в режимах “r” й “w” маркер поточної позиції встановлюється на початковий байт потоку, при відкритті в режимі “a” - на останній байт у кінці файлу. При виконанні кожної операції маркер переміщається на нову поточну позицію відповідно до кількості записаних або прочитаних байтів.
При відкритті існуючого файлу вказівник встановлюється в кінець файлу, якщо файл відкривається в режимі додавання даних і на початок файлу в усіх решту режимах.
Операції читання і запису виконуються в текучому положенні вказівника. Після відкриття файлу для читання перших десяти байт вказівник встановлюється на 10 позиції, звідки і починається наступна позиція вводу. Тому при послідовному вводі чи виводі даних з файлу нема необхідності звертати увагу на вказівник позиції функції вводу виводу самі про це вирішать.
Засоби прямого доступу дають можливість переміщати вказівник поточної позиції в файлі на потрібний байт. Для цього використовується функція. Зсув задається виразом або змінною і може бути від’ємним, тобто можливе переміщення як у прямому, так і у зворотному напрямках.
При повнішому контролі над операціями вводу виводу використовуються бібліотечні функції, які сприяють прямому доступу до даних у файлі, який означає, що дані у файл можна записувати в довільну позицію, так само можна з довільної позиції їх прочитати. Розглянемо бібліотечні функції для організації довільного доступу до даних файлів.
2. Функція управління маркером у файлі.Для управління маркером у файлі використовується бібліотечна функція fseek(). Вона дає можливості керування положенням маркера у файлі. З її допомогою можна встановити маркер в будь-яку позицію у файлі. Прототип функції fseek() знаходиться в бібліотечному файлі stdio.h і має вигляд:
int fseek(FILE *fp, long a1, int а2).
Аргумент fp є вказівником на структуру FILE, який повертається з функції fopen() при відкритті файлу.
Аргумент a1 задає відстань в байтах, на яку треба сумістити вказівник позиції аргументом a1.
Аргумент а2 задає точку, від якої обчислюється зміщення. Цей аргумент може мати одне з трьох значень — символічні константи, які наведено нижче.
Таблиця . Значення констант, які задають зміщення в функції fseek()
Константа
| Значення
| Опис
|
SEEK_SET
|
| Встановлення вказівника на байт з порядковим номером a1, починаючи з початку файлу
|
SEEK_CUR
|
| Зміщення вказівника на a1 байт від його текучого положення
|
SEEK_END
|
| Встановлення вказівника на відстань a1 байт, починаючи з кінця файлу
|
Функція повертає 0, коли встановлення маркера в задану позицію було виконано без помилок і ненульове значення у випадку помилки.
Довільний доступ до даних у файлі з допомогою функції fseek() продемонстровано програмою:
#include <stdlib.h>
#include <stdio.h>
main( ) {
FILE *fp;
int data, i, array[8]={1,5,8,34,56,34,89,100};
long a1;
fp = fopen("c:\\ff.txt", "wb"); /*Відкриття двійкового файлу для запису */
if (fp == NULL) {printf("\n Помилка відкриття файлу."); exit(1); }
i=fwrite(array, sizeof(int), 8, fp); /*Запис масиву у файл */
if ( i!= 8) {printf("\n Помилка запису даних у файл."); exit(1);}
fclose(fp);
fp = fopen("c:\\ff.txt ", "rb"); /*Відкриття файлу для читання */
if (fp == NULL) {printf("\n Помилка відкриття файлу."); exit(1);}
/*Присвоєння значення зміннійа1=4 */
а1=4;
/* Переміщення вказівника позиції до елементу з індексом а1 */
if ( (fseek(fp, (a1*sizeof(int)), SEEK_SET)) != 0)
{fprintf(stderr, "\nError using fseek()."); exit(1);}
fread(&data, sizeof(int), 1, fp); /*Читання одного цілого числа в змінну data*/
printf("\nElement %ld has value %d.", a1, data);
fclose(fp); }
3. Визначення поточного положення маркера у файлі.Для визначення поточного положення маркера у файлі використовується функція ftell(). Прототип функції знаходиться у бібліотечному файлі stdio.h і має вигляд:
long ftell(FILE *fp) ;
Аргументfp –є вказівником на структуру FILE,який повертається з функції fopen() при відкритті файлу. Функція повертає значення типу long, яке вказує номер поточного байта у файлі від його початку (початковий номер байта у файлі = 0). У випадку помилки функція повертає -1L (cont -1 типу long).
Приклад програми використання функції ftell():
#include <stdlib.h>
#include <stdio.h>
char msg[]="abcdefghijklmnopqrstuvwxyz";/*присвоєння масиву msg символьних значень*/
main(){
FILE *fp; /* Опис вказівника на структуру FILE */
char buf[6]; /*Опис масиву розмірності 6 */
fp = fopen("C:\\ff.TXT", "w")); /*Відкриття файлу для запису*/
if ( (fp = =NULL) { printf( "Помилка відкриття"); exit(1); }
fputs(msg, fp); /*Запис масиву у файл*/
if (fputs(msg, fp) == EOF) { printf("Помилка запису."); exit(1); }
fclose(fp); /*Закриття файлу для запису */
fp = fopen("C:\\ff.TXT ", "r"); /*Відкриття файлу для читання. */
if ( (fp == NULL) { fprintf (".Помилка відкриття "); exit(1); }
printf("\n=положення файлівого вказівника%ld", ftell(fp));
/*Результат Друк ftell(fp)=0 */
fgets(buf, 6, fp);/* Зчитування з файлу fp 5 символів. */
printf("\nAfter reading in %s, position = %ld", buf, ftell(fp));
/* Друк 5 символів з buf і положення файлового вказівника ftell(fp)=5 */
fgets(buf, BUFLEN, fp); /* Зчитування наступних 5 символів. */
printf("\n\nThe next 5 characters are %s, and position now = %ld", buf, ftell(fp));
/*Друк наступних 5 символів з buf і положення файлового маркера ftell(fp)=10*/
4. Встановлення положення маркера на початок файлу.Для встановлення положення маркера на початок файлу використовується функція rewind(). Прототип функції знаходиться у бібліотечному файлі stdio.h. і має вигляд:
void rewind(FILE *fp) ;
Аргументfp-є вказівником на структуру FILE,який повертається з функції fopen() при відкритті файлу. Функція використовується тоді, коли з файлу були вже зчитані дані і знову треба повернутися на початок файлу.
Приклад програми використання функціїrewind():
#include <stdlib.h>
#include <stdio.h>
char msg[]="abcdefghijklmnopqrstuvwxyz";/*присвоєння масиву msg символьних значень*/
main(){FILE *fp; /* Опис вказівника на структуру */
char buf[6]; /*Опис масиву розмірності 6 */
fp = fopen("C:\\ff.TXT", "w")); /*Відкриття файлу для запису*/
if ( (fp = =NULL) { printf( "Помилка відкриття"); exit(1); }
fputs(msg, fp); /*Запис масиву у файл*/
fclose(fp); /*Закриття файлу для запису*/
fp = fopen("C:\\ff.TXT ", "r"); /*Відкриття файлу для читання. */
if ( (fp == NULL) { fprintf (".Помилка відкриття "); exit(1); }
fgets(buf, BUFLEN, fp); /* Зчитування наступних 5 символів. */
rewind(fp); /*Повернення на початок потоку.*/
printf("\n %ld\n", ftell(fp));
fgets(buf, BUFLEN, fp);/*Зчитування з файлу fp 5 символів.*/
printf("\n%s\n", buf); /*Друк цих символів */
fclose(fp); }