Лекція 15. Керування буферізацією

Сайт: Навчально-інформаційний портал НУБіП України
Курс: Основи програмування
Книга: Лекція 15. Керування буферізацією
Надруковано: Гість-користувач
Дата: неділя, 15 лютого 2026, 19:42

1. Описання буферизації

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

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

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

2. Функції буферизації

У мові програмування С існує можливість створювати не системні буфери для обміну, або робити обмін небуферизуємим. 

Це можна здійснити за допомогою функцій:

1. void setbuf(stream, buffer);

2. int setvbuf(stream, buf, type, size)

0 – виділено;

<>0 – Помилка при виділенні.

Функція setvbuf дозволяє користувачеві керувати буферизацією і розміром буфера для потоку streamStream може посилатися на відкритий файл. Масив, на який указує buf, використовується як буфер, якщо він не є NULL, тобто потік не є буферизованим. Якщо потік буферизований, використовується тип, вказаний по type; цей тип може бути або _IONBF, або _IOFBF, або _IOLBF. Якщо використовується тип _IOFBF, розмір буфера визначається по size; якщо використовується тип _IOLBF або _IONBF, потік є НЕбуферизованим, а size і buf ігноруються.

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

Для вивантаження буфера можна використовувати функцію:

int fflush (FILE *stream)

Якщо заданий потік stream відкритий для виводу, то вміст буфера, пов'язаного з потоком stream функції fflush, записується у відповідний файл. Якщо потік відкритий для введення, то функція fflush очищає вміст буфера. Після виклику функції потік залишається відкритим. Для небуферизованого потоку застосування цієї функції не ефективно.

int flushall() функція записує вміст усіх буферів, пов'язаних з відкритими input потоками, у відповідні файли. Усі буфери, пов'язані з відкритими потоками, очищаються; наступна операція читання (якщо вона є) зчитує нові дані із вхідних файлів у буфер. Після виклику функції flushall усі потоки залишаються відкритими.

Дана функція повертає кількість відкритих потоків (вхідних і вихідних). У випадку помилки значення, що вертається, НЕМАЄ.

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

3. Текстовий та двійковий режим обміну

Можна відкривати потік у текстовому або двійковому режимі. Але ці режими мають певні особливості.

У текстовому режимі при введенні комбінація символів "повернути каретку - перевести строку" (\015 \012) перетвориться в один символ - перевести рядок. При висновку символ "перевести строку" перетвориться у два: \015, \012. Крім того, комбінація клавіш Ctrl+z (0х1а) сприймається як кінець файлу при висновку.

У двійковому режимі перетворення символів "ПК - ПС" не здійснюється.

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

На нижньому рівні використовується інше поняття - дескриптор файлу (handle). Це є ціле число, яке зв'язується з файлом і використовується для посилань на даний файл. Так стандартні потоки stdin, stdout, stderr, stdaux, stdprn мають відповідні дескриптори 0,1,2,3,4.

 int setmode (int handle, unsigned mode);( якщо функція повертає 0 - нормально, інакше –1)

 handle – дескриптор файла, mode – режим.

Режим задається двома константами в файле <fcntl.hO_BINARY    двійковий

O_TEXT           текстовий.

4. Інші функції обробки потоків

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

int feof (FILE *stream), яка передає нуль, якщо досягнуто кінець файлу при спробі прочитати символ, що випливає за останнім. Інакше її значення не нуль. 

int ferror (FILE *stream) дозволяє встановити причину помилки читання або запису. Якщо 0 - помилки не було. Якщо трапилася помилка, то внутрішній індикатор помилки файлу буде встановлено доти, поки потік не буде закритим або rewind, або clearrer.

Змінити назву файлу можна за допомогою функції:

int rename (char *oldname, char *newname) і поміняти oldname на нову назву newname. Якщо така процедура здійснилася успішно, то функція передає нуль. Цю функцію можна використовувати для запису файлу до іншого каталогу, але в межах одного обладнання.

 void rewind (stream), або void clearerr(stream) - яка записує в внутрішній індикатор помилки файлу нуль. Це ж здійснюється й при закритті потоку.

Знищити файл можна за допомогою функції:

int remove (const char *filename). Наступна спроба відкрити файл із таким іменем буде помилкою.

int fstat(handle,buffer) - одержує інформацію про відкритий файл, пов’язаний з даним handle, і запам'ятовує її в структурі, на яку вказує buffer.

buffer - структура, тип stat якої оголошений в <sys.h \ stat.h>, містить наступні поля.

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

Доступність

Шрифти Шрифти

Розмір шрифта Розмір шрифта

1

Колір тексту Колір тексту

Колір тла Колір тла

Кернінг шрифтів Кернінг шрифтів

Видимість картинок Видимість картинок

Інтервал між літерами Інтервал між літерами

0

Висота рядка Висота рядка

1.2

Виділити посилання Виділити посилання

Вирівнювання тексту Вирівнювання тексту

Ширина абзацу Ширина абзацу

0