Потоки і файли
Потік – це файл на диску або іншому пристрої, з якого дані можуть бути прочитані або в який можуть бути записані.
Для роботи з файлом необхідно визначити:
-
зовнішнє ім’я файлу;
-
покажчик на стандартну структуру типу FILE, яка містить інформацію про буфер ОП, режим роботи з файлом, поточну позицію у файлі тощо (описана в stdio.h).
Формат оголошення файлу як структури даних:
FILE *<покажчик>;
Відповідність між зовнішнім іменем файла на диску і покажчиком на файл у програмі встановлюється при відкритті файлу. При відкритті файлу також встановлюється і режим його обробки.
Основні режими відкриття файлів:
-
Режим
Призначення
Модифікація
t
b
“r”
відкрити для читання
“rt”
“rb”
“w”
створити новий файл тільки для запису
“wt”
“wb”
“a”
відкрити для дозапису в кінець файлу
“at”
“ab”
“r+”
відкрити існуючий файл для читання або запису
“r+t”
“r+b”
“w+”
створити новий файл для читання або запису
“w+t”
“w+b”
“a+”
відкрити файл в режимі читання і запису для дозапису
“a+t”
“a+b”
Додавання суфікса t до значення режиму є признаком відкриття текстових файлів; суфікса b – відкриття у двійковому режимі.
Функції обробки файлів (табл. 4) описані у заголовному файлі stdio.h.
Таблиця 4. Функції обробки файлів даних
|
Функція |
Призначення |
Формат |
Приклад використання |
|
|
Відкриття / закриття файлів |
||||
|
fopen |
Відкриття файлу f в режимі mode. Повертає покажчик на відкритий потік або NULL |
fopen(f,mode) |
pf = fopen(“f.dat”,“r”); |
|
|
fclose |
Закриття потоку f. Повертає 0 або EOF (якщо помилка) |
fclose(f) |
fclose(f); |
|
|
Читання із файла (введення із потоку) |
||||
|
fscanf |
Форматоване введення (зчитування даних) iз файла f по формату format в аргументи arg_1, …, arg_n. Повертає кількість введених значень або 0 |
fscanf(f,format,arg_1, …,arg_n) |
fscanf(f,“%d”,&n);
|
|
|
fread |
Читання із файла f заданої кількості (kol) елементів даних, кожен із яких має заданий розмір (size), і розміщення їх за покажчиком p. Повертає кількість прочитаних елементів або 0 |
fread(р,size,kol,f)
|
fread(&mas,sizeof(int),8,f); |
|
|
fgetc |
Читання символа із файла f. Повертає символ або EOF |
fgetc(f) |
c = fgetc(f); |
|
|
fgets |
Читання kol символів із файла f в рядок, на який вказує покажчик р (+’\0’) |
fgets(р,kol,f) |
fgets(buf,strlen(str),f); |
|
|
Запис у файл (виведення в потік) |
||||
|
fprintf |
Форматований запис у файл f по формату format списку аргументів arg_1, …, arg_n. Повертає кількість записаних елементів або 0 |
fprintf(f,format, arg_1, ..., arg_n) |
fprintf(f,“%d”,n);
|
|
|
fwrite |
Запис в кінець файла f заданої кількості (kol) елементів даних, кожен із яких має заданий розмір (size), вибираючи їх за покажчиком р. Повертає кількість елементів |
fwrite(р,size,kol,f) |
fwrite(&i,sizeof(int),1,f);
|
|
|
fputc |
Запис символа с в файл f. Повертає символ або EOF |
fputc(с,f) |
fputc(с,f); |
|
|
fputs |
Запис у файл f рядка, на який вказує покажчик р. Повертає покажчик на останній символ або EOF |
fputs(р,f) |
fputs(р,f); |
|
|
Доступ до компонент файлу |
||||
|
ftell |
Визначення поточного положення покажчика файлу f |
ftell(f)
|
ftell(f);
|
|
|
fseek |
Переміщення покажчика файлу f на вказану кількість байтів (kol_b) відносно вказаної позиції у файлі (tek). Повертає ціле число |
fseek(f,kol_b,tek)
|
fseek(f,11,SEEK_SET); fseek(f,ftell(f),SEEK_END); |
|
|
fflush |
Очистка потоку f |
fflush(f) |
fflush(f); |
|
|
feof |
Визначення кінця файла f. Повертає 0 або 1 |
feof(f) |
if (feof(f)!= NULL) … |
|
|
Хaрактеристика файла |
||||
|
fileno |
Повертає дескриптор (логічний номер) файла, зв’язаного з потоком f |
fileno(f) |
fileno(in); |
|
|
filelength |
Повертає в байтах довжину файла, зв’язанного з дескриптором handle (визначена у io.h) |
filelength(handle) |
len=filelength(fileno(f)); |
|
|
fstat |
Надає інформацію відносно відкритого файлу, зв’язанного з дескриптором handle, і запам'ятовує її в структурі збереження результатів stat (визначена у файлі stat.h) за покажчиком buf |
fstat(handle,buf) |
fstat(fileno(in),&buf); |
|
Приклад. На основі сформованого файла цілих чисел створити новий файл, в який переписати числа, що зустрічаються у вихідному файлі тільки один раз.
#include <stdio.h>
#include <sys\stat.h>
#include <conio.h>
#include <alloc.h>
#include <iostream.h>
FILE *in,*curr,*out; // покажчики на вхідний, проміжковий та вихідний файли
int i,j, // поточні значення елементів файлів
m, // індикатор співпадаючих елементів
ind_i=0,ind_j=0; // поточні номера елементів файлів
struct stat buf; // параметри файла: розмір, будова тощо
char c; // індикатор кінця введення
void Input(); // створення файла цілих чисел
void Output(FILE *); // виведення на екран вмісту файла
void CopyF(); // копіювання файлів
void DelDubl(); // пошук елементів файлів, що повторюються
//---------------------------- головна функцiя -----------------------------------------------------------------
main()
{ clrscr();
Input();
in=fopen("in.dat","r"); // відкрити файл для читання
printf("\nFile 1:");
Output(in);
CopyF();
curr=fopen("curr.dat","r");
printf("\nFile 2:");
Output(curr);
out=fopen("out.dat","w+"); // відкрити файл для запису і доповнення
DelDubl();
fclose(out);
out=fopen("out.dat","r");
printf("\nFile 3:");
Output(out);
while(!kbhit()); // очікування натиснення клавиші
return 0;
}
//-----------------------створення файла цілих чисел -----------------------------------------------
void Input()
{ in=fopen("in.dat","w");
do
{ cout<<"Input:"; scanf("%d",&i);
fprintf(in,"%d ",i);
cout<<"\nContinue?(y/n)"; cin>>c;
}
while(c!='n');
fclose(in);
}
//-------------------------- виведення на екран вмісту файла -------------------------------------------------
void Output(FILE *inn)
{ while(!feof(inn)) // поки не кінець файла,
{ fscanf(inn,"%d ",&i); // зчитати із файла в ОП
printf("%d ",i); // друк значень із ОП
}
}
//----------------------- копіювання файлів -----------------------------------------------
void CopyF()
{ curr=fopen("curr.dat","w+");
fseek(in,0L,SEEK_SET);
while(!feof(in))
{ fscanf(in,"%d ",&i);
fprintf(curr,"%d ",i);
}
fclose(curr);
}
//----------------------- пошук елементів файлів, що повторюються ------------------------------------
void DelDubl()
{ fseek(in,0L,SEEK_SET);
while(!feof(in))
{ fscanf(in,"%d ",&i); // читати елемент із вхідного файла
m=0;
ind_i++;
fseek(curr,0L,SEEK_SET);
ind_j=0;
while(!feof(curr))
{ fscanf(curr,"%d ",&j); // читати елемент із допоміжного файла
ind_j+=1;
if((i==j)&&(ind_i!=ind_j)) m++;
}
if (m==0) fprintf(out,"%d ",i);
}
}
Типи файлів
Pascal використовує ключове слово reset (встановити на початок) для процедури resct(var fd:FileTypc), одо готує файл для зачитування, та ключове слово rewrite для процедури rcwrite(var fd:FilcTypc). одо готує файл для запису.
Оскільки читати з файлу, якого не Ісігує, не виходить, процедура reset виробляє помилку, якодо файл Із зазначеною назвою не знайдено. Процедура rewrite просто замінює файл, якщо він існує і його можна модифікувати, або ж створює новий файл. Слід зауважити, що створення нового файлу або модифікація того, одо існує супроводжується зміною змісту файлу -каталога, в якому знаходиться Інформація про оброблюваний файл. Тому програма новина мати повноваження не тільки на модифікацію файлу, а й на модифікацію каталога. Більш детальні відомості про повноваження на доступ до файлів можна отримати Із системи допомоги використовуваної ОС.
Файл, одо його підготовлено до зачитування ігроцедурою reset, копіюється в буфер, тому зачитування даних практично не затримує роботи програми. Якщо файл не вмішується в буфері, копіюється тільки його частина, а наступні частини файлу операційна система намагається копіювати раніше, ніж буде використано весь зміст буферу. Наслідком такого поступового зачитування є тс, одо повернутись до вже прочитаних даних І иерезачита-ти їх одс раз можна тільки з самого початку файлу, використовуючи знов процедур)' reset.
З файлом, що його підготовлено до запису, ситуація ще складніша. Головною відміною є тс, одо під час запису система насправді не переписує нові дані замість старих, а створює новий файл з тією ж назвою, одночасно вивільнюючи місце на диску для наступного використання. Відповідно одразу пІстя виконання процедури rewrite втрачається можливість звертатись до
