Езикова библиотека GNU C glibc Кратък преглед на I-O
Повечето програми трябва да направят някакъв вход (четене на данни) или изход, или най-често и двете, за да направят нещо полезно. Библиотеката GNU C предоставя толкова голям избор от входни функции и изходни функции, че най-трудната част е да решите коя функция е най-подходящата!
Тази глава въвежда понятия и терминология, свързани с входа и изхода. Други глави, свързани с GNU I/O съоръжения:
- Глава 7 [I/O на потоци], която описва функции на високо ниво, които работят с потоци, включително форматиран вход и изход.
- Глава 8 [Вход/изход на ниско ниво], която описва основни входно/изходни и контролни функции на файлови дескриптори.
- Глава 9 [Интерфейс на файловата система], която описва функции за операции с директории и за управление на файлови атрибути, режими на достъп и собственост.
- Глава 10 [Piping и FIFO (First In First Out)], която включва информация за основните междупроцесорни комуникации.
- Глава 11 [Сокети], която описва по-сложен IPC с поддръжка за работа в мрежа.
- Глава 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 C, няколко последователни знака `/' са еквивалентни на един знак `/'.
Процесът на определяне към кой файл се отнася името на файл се нарича присвояване на име на файл. Това се прави чрез изследване на компонентите, съставляващи името на файла, отляво надясно и поставяне на всеки следващ компонент в директорията, наречена от предишния компонент. Разбира се, всеки от файловете, наречени директории, трябва действително да съществува и да бъде директория вместо обикновен файл и да има подходящите разрешения, за да бъде достъпен за различни процеси; иначе грешноприсвоено име на файл.
Ако името на файла започва с "/", се приема, че първият компонент в името на файла е основната директория на процеса (обикновено всички процеси в системата имат една и съща основна директория). Това име на файл се нарича абсолютно име на файл.
В противен случай първият компонент в името на файла е текущата работна директория (вижте раздел 9.1 [Работна директория]). Този вид име на файл се нарича име на файл с директен достъп.
Компоненти на името на файла "." ("точка") и ".." ("точка - точка") имат специално значение. Всяка директория има записи за тези компоненти на имена на файлове. Компонентът на името на файла "." се отнася до самата директория, докато компонентът ".." на името на файла се отнася до родителската директория (директорията, която съдържа връзката към въпросната директория). Като специален случай, ".." в основната директория се отнася до самата основна директория, тъй като тя няма родител; следователно "/.." е същото като "/".
Ето няколко примера за имена на файлове:
За разлика от някои други операционни системи, системата GNU няма вградена поддръжка за файлови типове (или разширения) или версии като част от синтаксиса на файловото име. Много програми и помощни програми използват конвенции за именуване на файлове, например файлове, съдържащи изходен текст на C, обикновено се именуват с добавен ".c", но няма нищо директно във файловата система, което да налага този вид конвенция.
Грешки, свързани с имена на файлове
Функциите, които приемат имена на файлове като аргументи, обикновено откриват тези errno - условия за грешка по отношение на синтаксиса на имената на файловете. Тези грешки се наричат в това ръководство обикновени грешки в синтаксиса на името на файла.
В системата GNU няма наложено ограничение за общата дължина на иметофайл, но някои файлови системи може да имат ограничения за дължина на компонента.
Преносимост на името на файла
Правилата за синтаксиса на файловите имена, обсъдени в раздел 6.2 [Имена на файлове], са правилата, които обикновено се използват от системата GNU и други POSIX системи. Други операционни системи обаче може да използват различни конвенции.
Стандартът POSIX.1 позволява на реализациите да поставят допълнителни ограничения върху синтаксиса на името на файла, по отношение на това какви знаци са разрешени в имената на файлове и върху дължината на името на файла и низовете на компонента на името на файла. В системата GNU обаче не е нужно да се тревожите за тези ограничения; всеки знак, с изключение на нулевия символ, е разрешен в низ на име на файл и няма ограничения за дължината на низовете на името на файла.