Бібліотека мови C GNU glibc Короткий огляд вводу-виводу
Більшість програм повинні робити деяке введення (читання даних) або висновок, або найчастіше обидва, щоб зробити щось корисне. Бібліотека GNU С забезпечує такий великий вибір функцій введення та функцій виведення, що найважча частина вирішити, яка функція є найбільш підходящим!
Цей розділ представляє поняття та термінологію, що мають відношення до введення та висновку. Інші розділи, які стосуються засобів введення-виведення GNU:
- Глава 7 [Введення-виведення на потоках], яка описує функції високого рівня, що функціонують на потоках, включаючи введення, що форматується, і виводить.
- Глава 8 [Введення-виведення низького рівня], яка описує базисне введення-виведення та функції управління на описниках файлу.
- Розділ 9 [Інтерфейс файлової системи], який описує функції для операцій на каталогах та керування атрибутами файлу, режимами доступу та монопольного використання.
- Глава 10 [Трубопроводи та FIFO (перший зайшов – перший вийшов)], яка включає інформацію щодо базисних міжпроцесорних засобів зв'язку.
- Глава 11 [Гнізда], яка описує складніший міжпроцесорний засіб зв'язку з підтримкою для роботи з мережами.
- Розділ 12 [Інтерфейс терміналу низького рівня], який описує функції зміни як введення так і виведення на термінал або інший послідовний пристрій.
З'єднання з відкритим файлом представляється як потік або як описувач файлу. Ви передаєте його як аргумент функцій, які роблять фактичне читання або операції запису. Деякі функції чекають на потоки, а деякі розроблені для взаємодії з описниками файлу.
Потоки та описувачі файлу
Коли Ви хочете здійснювати введення або виводити файл, Ви маєте вибір з двох базисних механізмів дляпредставлення з'єднання між вашою програмою та файлом. Це описувачі файлу та потоки. Описувачі файлу видаються як об'єкти типу int, тоді як потоки представляються як об'єкти FILE* (покажчики).
Описувачі файлу забезпечують примітивний інтерфейс низького рівня для операцій введення та виведення. І описувачі файлу, і потоки можуть представляти з'єднання з пристроєм (типу терміналу), з трубопроводом або з гніздом для повідомлення з іншим процесом, також як з нормальним файлом. Але, якщо Ви хочете здійснювати операції керування, які є специфічними для специфічного виду пристрою, Ви повинні використовувати описувач файлу; немає жодних засобів, щоб використовувати для цього потоки. Ви також повинні використовувати описувачі файлу, якщо ваша програма повинна робити введення або виводити в спеціальних режимах, типу неблоковане (або опитане) введення (див. розділ 8.10 [Прапори стану файлу]).
Потоки забезпечують інтерфейс вищого рівня, що базується на примітивних засобах описувача файлу. Інтерфейс потоку добре обробляє всі види файлів, єдина складність – три стилі буферизації, яку Ви можете вибирати (див. розділ 7.17 [Буферизація потоку]).
Основна перевага використання інтерфейсу потоку - те, що набір функцій для виконання фактичного введення та виведення (на противагу операціям управління) на потоках є набагато багатшим і потужнішим, ніж відповідні засоби для описників файлу. Інтерфейс описувача файлу забезпечує лише прості функції для пересилання блоків символів, а інтерфейс потоку забезпечує потужний форматований введення та виведення (printf і scanf) також як функції для символьно- та рядково-орієнтованого введення та виведення.
Оскільки потоки виконані в термінахописувачів файлу, Ви можете витягувати описувач файлу з потоку та виконувати операції низького рівня безпосередньо на описувачі файлу. Ви також можете спочатку відкривати з'єднання як описувач файлу, а потім робити потік, пов'язаний з цим описувачем файлу.
Взагалі, Ви повинні обмежитися використанням потоків, якщо немає певної специфічної операції, яка може бути виконана тільки на описувачі файлу. Якщо Ви - програміст-початківець і не впевнені, які функції використовувати, ми пропонуємо Вам концентруватися на функціях, що форматуються (див. розділ 7.11 [Форматований введення] і розділ 7.9 [Форматований висновок]).
Якщо Ви думаєте про перенесення ваших програм на не-GNU системи, Ви повинні також усвідомлювати, що описувачі файлу не такі переносні, як потоки. Ви можете очікувати, що будь-яка ANSI система підтримує потоки, але не-GNU системи не можуть підтримувати описувачі файлу взагалі або можуть виконувати лише підмножина функцій GNU, які функціонують на описувачі файлу. Більшість функцій описувача файлу в бібліотеці GNU включено до стандарту POSIX.1.
Позиція файлу
Один із атрибутів відкритого файлу – позиція файлу, яка стежить, де у файлі наступний символ має прочитатися чи написатись. У системі GNU, і всіх POSIX.1 системах, позиція файлу - це ціле число, що представляє число байтів від початку файла.
Позиція файлу зазвичай встановлюється на початок файлу, коли він відкритий, і кожного разу, коли символ читається або пишеться, позиція файлу збільшується. Іншими словами, доступ до файлу зазвичай послідовний.
Звичайні файли дозволяють читати або записувати будь-яку позицію всередині файлу. Деякі інші види файлів також можуть дозволяти це. Файли, які дозволяють це іноді згадуються як файли прямогодоступу. Ви можете змінювати позицію файлу, використовуючи функцію fseek на потоці (див. розділ 7.15 [Позиціонування файлу]) або функцію lseek на описувачі файлу (див. розділ 8.2 [Примітиви введення - виведення]). Якщо Ви намагаєтесь змінювати позицію файлу у файлі, який не підтримує довільний доступ, Ви отримаєте помилку ESPIPE.
Потоки та описувачі, які відкриті для дописування, обробляються особливо для виведення: виведення в такі файли завжди конкатенується послідовно до кінця файлу, незалежно від позиції файлу. Але, позиція файлу все ще використовується, щоб керувати, де у файлі виконувати читання.
Фактично кожне відкриття файлу створює окрему позицію файлу. Таким чином, якщо Ви відкриваєте файл двічі навіть у тій самій програмі, Ви отримуєте два потоки або описувачі з незалежними позиціями файлу.
Навпаки, якщо Ви відкриваєте описувач а потім дублюєте його, щоб отримати інший описувач, ці два описувачі спільно використовують ту саму позицію файлу: зміна позиції файлу одного описувача буде впливати на інший.
Щоб відкрити з'єднання з файлом, або виконувати інші операції типу видалення файлу, Ви потребуєте деякого способу звернення до файлу. Майже всі файли мають імена, які надаються рядками.
Ці рядки називаються іменами файлу. Ви визначаєте ім'я файлу, щоб вказати, який файл потрібно відкрити або обробити.
Цей розділ визначає угоди для імен файлу і як операційна система працює з ними.
Щоб розуміти синтаксис імен файлу, Ви повинні зрозуміти, як файлову систему організовано за допомогою ієрархії каталогів.
Каталог - це файл, який містить інформацію, що сполучає імена інших файлів; ці асоціації називаються виходами каталогуабо узами. Іноді люди говорять "файли в каталозі", але фактично каталог тільки містить покажчики на файли, а не файли безпосередньо.
Ім'я каталогу, що містить файл, називається компонентом імені файлу. Взагалі, ім'я файлу це послідовність з одного або більше таких компонентів, що відокремлюються символом похилої риси вправо ("/").
Деякі інші документи, типу POSIX стандарту, використовують термін шлях для того, що ми називаємо ім'я файлу, і компонент шляхи для того, що цей посібник викликає компонент імені файлу. Ми не використовуємо цю термінологію, тому що "шлях" - це щось цілком відмінне (список каталогів для пошуку), і ми думаємо, що "ім'я шляху", яке використовується для чогось ще буде заплутувати користувачів. У документації GNU ми завжди використовуємо "ім'я файлу" та "компонент імені файлу" (або іноді тільки "компонент", де контекст очевидний).
Ви можете знайти більш детальну інформацію щодо операцій з каталогами у Розділі 9 [Інтерфейс файлової системи].
Призначення імені файлу
Ім'я файлу складається з компонентів імені файлу, що відокремлюються похилою межею вправо ("/"). У системах, які підтримує бібліотека GNU С, багаторазові послідовні символи `/' еквівалентні одиночному символу `/'.
Процес визначення, якого файлу належить ім'я файлу називається призначення імені файла. Це реалізується дослідженням компонентів, які становлять ім'я файлу зліва направо, і розміщенням кожного послідовного компонента в каталозі, іменованому попереднім компонентом. Звичайно, кожен із файлів, які названі каталогами, повинен фактично існувати, і бути каталогом замість регулярного файлу, і мати відповідні права, щоб бути доступним різним процесам; інакше неправильнопризначено ім'я файлу.
Якщо ім'я файлу починається з "/", першим компонентом в імені файлу приймається кореневий каталог процесу (зазвичай усі процеси в системі мають той самий кореневий каталог). Таке ім'я файлу називається абсолютним ім'ям файлу.
Інакше першим компонентом в імені файлу є поточний робочий каталог (див. розділ 9.1 [Робочий каталог]). Цей вид імені файлу називається ім'ям прямого доступу.
Компоненти імені файлу "." ("точка") та ".." ("точка - точка") мають спеціальні значення. Кожен каталог має входи цих компонентів імені файлу. Компонент імені файлу "." відноситься до каталогу безпосередньо, в той час як компонент імені файлу ".." відноситься до каталогу попереднього рівня (каталог, який містить зв'язок для каталогу, що розглядається). Як окремий випадок, ".." у кореневому каталозі відноситься до кореневого каталогу безпосередньо, тому що він не має жодного з батьків; таким чином "/.." теж що і "/".
Ось кілька прикладів імен файлу:
На відміну від деяких інших операційних систем, система GNU не має вбудованої підтримки типів файлів (або розширень) або версій як частин синтаксису імені файлу. Багато програм та утиліт використовують угоди для імен файлів, наприклад, файли, що містять вихідний текст C зазвичай мають імена, з доданим ".c" але безпосередньо у файловій системі немає нічого, що наказує цей вид угоди.
Помилки, пов'язані з іменами файлів
Функції, які приймають як аргументи імена файлів зазвичай, виявляють ці errno - умови помилки щодо синтаксису імені файлу. Ці помилки згадуються в цьому посібнику як звичайні синтаксичні помилки імені файлу.
У системі GNU немає жодного накладеного обмеження повної довжини іменіфайл, але деякі файлові системи можуть мати обмеження довжини компонента.
Перенесення імен файлу
Правила для синтаксису імен файлу, що обговорюються в розділі 6.2 [Імена файлу], є правилами, які зазвичай використовуються системою GNU та іншими POSIX системами. Однак інші операційні системи можуть використовувати інші угоди.
Стандарт POSIX.1 дозволяє, щоб реалізації помістили додаткові обмеження на синтаксис імені файлу щодо того, які символи дозволяються в іменах файлу і на довжину імені файлу і рядків компонентів імені файлу. Однак у системі GNU Ви не повинні хвилюватися щодо цих обмежень; будь-який символ за винятком порожнього символу допускається в рядку імені файлу, і немає обмежень на довжини рядків імені файлу.