Програмування С, С++теорія та практика (частина 1)
1.15.3 Використання дескрипторів файлів
В мові Сі передбачений ще один механізм роботи з файлами - використання дескрипторів. Файли, які відкриваються таким чином не розраховані на роботу з буферами та форматованими даними.
На початку роботи будь-якої програми відкриваються п’ять стандартних потоків зі своїми дескрипторами.
|
Таблиця 1.15. Дескриптори стандартних потоків введення-виведення
|
Але будь-яка програма може і явним чином відкривати будь-які файли з дескрипторами.
Функції, які працюють з дескрипторами файлів, описані в модулі
ів.к.
Файли відкривається функцією ореп(), яка повертає дескриптор файлу:
іпі ореп(соп5і сИаг *раіІі, іпі ассе55 [ , ип5ідпесІ тосіе ] );
Параметр раік задає ім’я файлу відкриття. Параметр ассезз визначає режим доступу до файлу. шоіїе є не обов’язковим та задає режим відкриття файла.
Параметр ассезз формується за допомогою операції АБО (|) з переліку прапорців.
0_РООІ\ІІ_У тільки для читання
0_МР0І\ІІ_У тільки для запису
О_Р0МР для читання і запису
0_СРЕАТ створення нового файлу
0_ТРІІІ\ІС якщо файл існує, то він стає порожнім
0_ВІИАРУ двійковий файл
0_ТЕХТ текстовий файл
Параметр тойе може приймати наступні значення 5_ІМРІТЕ дозволити запис
3_ІРЕА0 дозволити читання
Використання функції/ореп() демонструє наступний приклад :
#іпс1ийе <з'Ьгіпд.Ь>
#іпс1ийе <з'Ьйіо.Ь>
#іпс1ийе <£сп£1.Ь>
#іпс1ийе <іо.Ь> іп£ таіп^оій.)
{
іп£ Ьапй1е;
сЬаг тзд[] = "Не11о мог1й";
і£ ((Ьапй1е = ореп("ТЕ8Т.ТХТ", 0_СКЕАТ | 0_ТЕХТ)) ==
-1)
{
реггог("Еггог:"); ге'Ьигп 1;
}
мгі^е(ЬапЛ1е, тзд, з'Ьг1еп(тзд)); с1озе(ЬапЛ1е) ; ге'Ьигп 0;
}
Як видно з прикладу, файл, відкритий функцією ореп() повинен бути закритий за допомогою функції сІо$е().
іпі сІо5е( і пі ИапСіе);
Читання і запис даних при роботі з файлами, що визначаються дескрипторами капіїІе, здійснюється функціями мгіІе() і теай().
іпі геаС(іпі ИапСІе, уоіС *Ьи1, ип5ідпеС Іеп);
іпі мгііе(іпі ИапСІе, уоіС *Ьи1, ип5ідпеС Іеп);
В наведених функціях Ьи/ - покажчик на буфер, з якого записується в файл інформація, або в який читається Іеп байтів з файла.
Буферизація потоків. В мові Сі існує ряд функцій, які дозволяють керувати буферизацією потоків.
Функція $еіЬи/() дозволяє користувачу встановлювати буферизацію вказаного потоку іігеат. Синтаксис функції $еґЬи/():
уоіС 5еіЬиі(ПІ_Е *5ігеат, сИаг *Ьи1);
Значення аргументу іігеат повинне відповідати стандартному або вже відкритому потоку.
Якщо значення аргументу Ьи//ег рівне МПЬЬ, то буферизацію буде відмінено. Інакше, значення аргументу Ьи//ег буде визначати адресу масиву символів довжини БПР8І2, де БПР8І2 - розмір буфера (константа, визначена в зїйіо.к).
Визначений користувачем буфер використовується для буферизованого введення/виведення для вказаного потоку іігеат
замість буферу, що виділяється системою по замовчуванню.
Потоки 8їйегг і 8їйоиї по замовчуванню небуферизовані, але для них можна встановлювати буферизацію засобами хеіЬи/.
Примітка. Наслідки буферизації будуть непередбаченими, якщо тільки функція і'еіЬи/() не викликана зразу вслід за функцією /ореп() або /еекО для заданого потоку.
В мові Сі для керування буферизацією потоків існує ще одна функція: $еІуЬи/(). Вона дозволяє користувачу керувати буферизацією та розміром буфера потоку іігеат. Синтаксис :
іпі 5еіуЬиі(ПІ_Е *5ігеат, сИаг *Ьи1, іпі іуре, 5іге_і 5іге);
Потік іігеат повинен відноситися до відкритого потоку.
Якщо значення параметру Ьи/ не ШПЬЬ, то масив, адреса якого задається значенням параметра Ьи/ буде використовуватися в якості буфера.
Якщо потік буферизується, значення параметра іуре визначає тип буферизації. Тип буферизації може бути або _ІОИБР, або _ІОРВР, або _ІОЬВР.
Якщо тип рівний _ІОРВР або _ІОЬВР, то значення параметра зіге використовується як розмір буфера.
Якщо тип рівний _ІОМВР, то потік небуферизований, і значення параметрів зіге і Ьи/ігноруються.
Допустиме значення параметра ше: більше 0 і менше, ніж максимальний розмір цілого (іпі).
Значення констант _ІОИВР, _ІОРВР та _ІОЬВР визначені у файлі зійіо.к.
_І0ЕВЕ 0 /* буферизація на повний об'єм буфера */
_І0ЬБЕ 1 /* порядкова буферизація */
_І0МВЕ 2 /* потік не буферизується */
Для примусового виштовхування буферу можна використовувати функцію//7шк(). Її синтаксис :
іпі їїіи5Іі(ПІ_Е *5ігеат);
Дана функція виштовхує вміст буфера, зв’язаного з потоком іігеат. Потік залишається відкритим. Якщо потік небуферизований, то виклик функції//їи$к() не викличе ніяких ефектів.
Буфер потоку автоматично виштовхується, коли він заповнюється, коли закривається потік або коли програма завершує своє виконання.
Приклад 1.
#іпс1ийе <з'Ьйіо.Ь>
#іпс1ийе<сопіо.Ь> сЬаг ои^Ьи£[виЕ8І2]; іп£ таіп^оій.)
{
с1гзсг () ;
зе'ЬЬи£(з'Ьйои'Ь, ои^Ьи£);
ри'Ьз("ТЬіз із а їезї о£ Ьи££егей ои^ри^.\п\п");
ри'Ьз("ТЬіз ои'Ьри'Ь мі11 до іп£о оиЬЬи£\п") ;
риЬз("апй иоп'Ь арреаг ип£і1 £Ье Ьи££ег\п");
риЬз("£і11з ир ог ме £1изЬ £Ье зїгеат.\п") ;
де£сЬ() ;
££1изЬ(з^йои^);
де'ЬсЬО ; ге'Ьигп 0;
}
Приклад 2.
#іпс1ийе <з,Ьгііо.Ь> іп£ таіп^оігі)
{
ЕІЬЕ *іпри£, ♦ои'Ьри'Ь; сЬаг Ьи£г[512];
іпри£ = £ореп("£і1е.іп", "г+Ь"); ои'Ьри'Ь = £ореп("£і1е.ои^", "м"); і£ (зе'Ь^Ьи^іпри'Ь, Ьи£г, _ІОЕВЕ, 512) != 0)
ргіп^£("Помилка встановлення буферизації\ для вхідного файла\п");
е1зе
ргіп^£("Для вхідного файла встановлено \ буферизацію\п");
і£ (зе'Ь^Ьи£(ои'Ьри'Ь, НЦЬЬ, _ІОЬБЕ, 132) != 0)
ргіп^£("Помилка встановлення буферизації \ для вихідного файла\п");
е1зе
ргіп^£("Буфер для вихідного файла \ встановлено\п") ;
£с1озе(іпри£);
£с1озе(ои^ри^); ге'Ьигп 0;
}
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
