Окрім функцій для доступу до файлів як до потоків, Turbo С включає велику групу функцій префіксного доступу до файлів, або, як інколи кажуть, системних викликів, чи процедур нижнього рівня (Low Level File I/O Rutines). Префіксні функції не виконують додаткової буферизації інформації і відразу звертаються до функцій MS-DOS.
Префіксне відкриття файлу виконують дві функції бібліотеки Turbo С: ореn() та _ореn(). Перша з них максимально наближена до однойменного системного виклику ОС UNIX, друга є специфічною для MS-DOS формою префіксного відкриття файлу. Обидві функції звертаються до одних і тих функціональних викликів MS-DOS: відкриття файлу (АН=3Dh); створення файлу (АН=3Ch), якщо задане створення файлу. Далі наведена специфікація розглянутих функцій.
#include <io.h>
int open( const char *pathname, int access [, unsigned mode] )
Відкриває файл для читання або запису. UNIX-подібна форма відкриття
(створення) файлу. В випадку успішного відкриття файлу, на ASCIIZ-рядок
специфікації якого вказує pathname, повертає префікс файлу; в протилежному
випадку повертає (-1) і задає в зовнішню змінну errno код помилки. Ціле число
access визначає права доступу, що запрошуються при відкритті файлу. Вони
задаються об’єднанням операції АБО (ЧИ) символьних констант, опис яких
міститься в файлі <fcntl.h> (Табл. 8).
#include <io.h>
int _open( const char *filename, int oflags )
Функція орієнтована на MS-DOS. Відкриває файл для читання або запису. В
випадку успішного відкриття файлу, на ASCIIZ-рядок специфікації якого вказує
filename, повертає префікс файлу; в противному випадку повертає (-1) і задає в
зовнішню змінну errno код помилки. Значення oflags формується об’єднанням по
АБО (ЧИ) символьних констант, описаних в файлі <fcntl.h> (Табл. 8). Прапори, що не підтримуються MS-DOS, ігноруються.
Табл. 8. Константи прав доступу і режимів створення файлів
Константа |
Функція |
O_RDONLY |
Файл відкривається тільки для читання. Спроба запису в файл викликає
повернення помилки запису. Якщо файл заданої специфікації не існує,
повертається помилка при відкритті файлу |
O_WRONLY |
Файл відкривається тільки для запису. Спроба читання з такого файлу
викликає повернення помилки функцією читання. Так може відкриватися тільки
файл, не позначений при створенні як “тільки для читання”. Якщо файл з так
заданою специфікацією не існує, новий файл створюється тільки в тому випадку,
коли заданий прапор створення файлу, у протилежному випадку повертається помилка
при відкритті файлу |
O_RDWR |
Файл відкривається для запису і читання. Так може відкриватися тільки
існуючий файл, не позначений при створенні як “тільки для читання”. Якщо файл
не існує і вказано створення файлу, він буде створений; в протилежному
випадку повертається помилка при відкритті файлу |
O_CREAT |
Прапор створення файлу. Якщо файл зі специфікацією pathname не існує,
він буде створений в заданій специфікацією директорії заданого накопичувача.
При створенні файлу буде використаний третій аргумент функції - mode. Він
формується об’єднанням наступних символічних констант, опис яких міститься в
файлі <sys\stat.h>: S_IFMT - маска типу файлу. Задається обов’язково, якщо встановлюється
тип файлу. MS-DOS не підтримується; S_IFDIR - файл є директорією; Turbo С створює звичайний файл з
бітом “тільки для читання” байта атрибута файлу, а не директорій; S_IFIFO - FIFO-спеціальний файл. MS-DOS не підтримує. S_IFCHR – спеціальний символьний файл; S_IFBLK – блоковий спеціальний файл. MS-DOS не підтримується; S_IFREG - регулярний файл (за замовчанням); S_IREAD - володар має право читати файл. В MS-DOS відповідає
створенню файлу з бітом “тільки для читання” байта атрибуту. S_IWRITE - володар має право записувати в файл. В MS-DOS створюється
звичайний файл з архівним бітом байта атрибуту елементу директорії; S_IEXEC - володар має право запускати файл на виконання MS-DOS не
підтримується. |
O_TRUNC |
Файл відкривається з відсіканням попереднього вмісту. |
O_EXCL |
Файл відкривається в режимі виняткового доступу: спроби інших
процесів (ОС UNIX) або інших комп’ютерів мережі, якщо завантажені спец.
програми мережевої підтримки (MS-DOS), будуть завершуватися помилкою
відкриття файлу. |
O_APPEND |
Покажчик запису-читання файлу встановлюється на кінець файлу. |
O_ТЕХТ |
Файл відкривається в текстовому режимі |
O_BINARY |
Файл відкривається в бінарному режимі. |
O_NOINHERIT |
Нащадок не успадковує файл |
Табл. 9. Режими створення файлів
Константа |
Функція |
FA_RDONLY |
Створюється файл з атрибутом “тільки для читання” |
FA_HIDDEN |
Створюється файл з атрибутом “що приховуються” |
FA_SYSTEM |
Створюється файл з атрибутом “системний” |
FA_LABEL |
Посилання на мітку тому. Елемент директорії буде відповідати мітці тому. Мітка тому записується тільки в кореневу директорії |
FA_DIREC |
Створений файл є директорією; фактично створюється звичайний файл з атрибутом “тільки для читання” |
FA_ARCH |
Створюється файл з атрибутом “архівний” |
Окрім перерахованих функцій, файл відкривається і при його створенні. Turbo С підтримує наступні функції для створення файлів: creat(), _creat(), creatnew() і creattemp(). Далі наведені специфікації цих функцій.
#include <io.h>
int _creat( const char *path, int attrib )
int creat( const char *path, int amode )
Створюють новий файл або перезаписують існуючий; creat() є
UNIX-подібною формою функції, _creat() – орієнтована на MS-DOS форма функції. В
випадку успішного створення і відкриття файлу, на ASCIIZ-рядок специфікації
якого вказує pathname, повертає префікс файлу; в протилежному випадку повертає
(-1) і задає в зовнішню змінну егrno код помилки. Значення attrib формується
об’єднанням по АБО символічних констант, описаних в файлі <dos.h>, і
визначає, які біти будуть встановлені в байті атрибуту елементу директорії,
який створюється функцією (Табл. 9).
Значення amode в функції creat() формується об’єднанням по АБО
символічних констант, опис яких міститься в файлі <stat.h> (Табл. 8): S_IFMT, S_IFDIR. S_IFIFO, S_IFCHR, S_IFBLK,
S_IFREG, S_IREAD, S_IWRITE і S_IEXEC.
#include <io.h>
int creatnew( const char *path, int attrib )
Ідентична функції _creat(), але на відміну від неї повертає помилку,
якщо файл вже існує. В випадку успіху повертає префікс файлу; в протилежному
випадку повертає (-1) і записує код помилки в зовнішню змінну errno . Параметр
attrib задає байт атрибуту файлу і формується операцією порозрядного АБО
символічних констант.(Табл. 9). Значення attrib=0 призводить до створення
нормального архівного файлу. Функція вимагає версії MS-DOS 3.0 і старших.
#include <io.h>
int creattemp( char *path, int attrib )
Генерує унікальне ім’я файлу і створює файл з таким ім’ям в директорії,
що задається рядком, на яку вказує path. Рядок повинен завершуватися символом
‘\’. Новий файл створюється з байтом
атрибуту, що задається параметром attrib. Він формується операцією порозрядного
АБО символьних констант (Табл. 9). Ім’я файлу копіюється в буфер path, так що належить
зарезервувати достатньо місця для специфікації файлу. У випадку успіху повертає
префікс файлу; а в протилежному випадку повертає (-1) і записує код помилки в
зовнішню змінну errno. Після завершення програми не відбувається автоматичного
знищення створеного файлу. Функція вимагає версії MS-DOS 3.0 і старших.
Закриття файлів, відкритих для префіксного доступу, виконується явно функціями close() і _close(). Неявне закриття файлів, відкритих програмою, виконує ОС при завершенні програми. При цьому відбувається флешування внутрішніх буферів MS-DOS відкритих файлів. Рекомендується практикою явне закриття файлів, що економить внутрішню системну пам’ять MS-DOS. Далі приводиться специфікація функцій закриття файлів:
#include <io.h>
int _close( int handle )
int close( int handle )
Закривають файл, відкритий для префіксного доступу. Параметр handle
префікс файлу, повернений будь-якою з функцій префіксного створення (відкриття)
файлу. В випадку успіху функції вертають 0, в протилежному випадку вертають
(-1) і в зовнішню змінну errno записують код помилки.
Наведемо приклади використання розглянутих функцій. Наступна програма відкриває файл для префіксного доступу і записує туди тестовий рядок string; специфікація файлу задається першим аргументом командного рядку при запуску програми:
/* L3_12.C */
#include <stdio.h>
#include <fcntl.h>
#include <stat.h>
#include <io.h>
char string[ ] = “Тестовий рядок для запису в файл”;
main( int argc, char **argv ) {
int handle;
if( argc < 2 ) {
printf( “\а Використання програми:
%s ИМ’Я_ФАЙЛУ \n”, argv[0] );
return( 1 );
}
if( ( handle = open( argv[1],
O_TRUNC | O_CREAT | O_WRONLY |
O_TEXT, S_IWRITE ) )== -1 ) {
printf( “Помилка відкриття файлу %s
\n ”, argv[ 1 ] );
perror( “Причина помилки:”);
return( 2 );
}
write( handle, string, sizeof( string
) );
close( handle );
return( 0 );
}
Ця програма відкриває файл для запису і поміщує туди всі символи з масиву string. Файл відкривається в текстовому режимі. У тому випадку, якщо файл із заданою специфікацією буде відсутній, буде створений і відкритий для запису новий файл. Якщо файл існує, його попередній вміст буде зруйновано, бо задано прапор O_TRUNC. Без цього прапору будуть переписуватися тільки перші 33 байти.
Наведена далі програма ілюструє використання MS-DOS орієнтованої форми створення файлу. Для прикладу створюється файл з бітами “архівний”, “що приховується” і “системний” байта атрибуту. Після створення файлу із заданою у командному рядку специфікацією туди записується тестовий рядок. Після цього вміст блоку в 512 байт файлу виводиться на стандартний пристрій виведення. Слід використовувати з обережністю атрибути “що приховується” та “системний”, бо такі файли не показуються в списку файлів директорія, одержаного командою dir і не можуть бути усунені командою del до тих пір, доки не буде подавлений байт “що приховується”.
Програма L3_13.C створює та відкриває файл для префіксного доступу. Специфікація файлу, що відкривається задається першим аргументом командного рядка при запуску програми:
/*L3_13. C*/
#include <sfdio.h>
#include <stat.h>
#include <io.h>
#include <dos.h>
char string[512] = “Тестовий рядок для запису в файл”;
main( argc, char**argv ) {
int handle;
if( argc < 2 ) {
puts( “Використання програми. L3_13
ИМ’Я_ФАЙЛУ” );
return( 1 );
}
if( ( handle = _creat( argv[ 1 ],
FA_ARCH | FA_SYSTEM |
FA_HIDDEN)) == -1 ) {
printf( “Помилка відкриття файлу.
%s \n ", argv[ 1 ] );
perror( “Причина помилки: “ );
return( 2 );
}
write( handle, string, sizeoff( string
) );
read( handle, string, 512);
write( 1, string, 512 );
close( handle );
return( 0 );
}
Приведена далі програма ілюструє використання UNIX-подібної форми створення файлу:
/*L3_14. C*/
#include<stdio.h>
#include<sfat.h>
#include <io.h>
char string [512]="Тестовий рядок для запису у файл";
main( int argc, char** argv ) {
int handle;
if( argc < 2 ) {
puts( “Використання програми: L3_14
ИМЯ_ФАЙЛУ “ );
return( 1 );
}
if( ( handle = creat( argv[ 1 ],
S_IWRITE ) ) = -1 ) {
printf( “Помилка відкриття файлу %s
\n ”, argv[ 1 ] );
perror( “Причина помилки: “ );
return( 0 );
}
write( handle, string, sizeof( string
) );
read( handle, string, 512 );
write( 1, string, 512 );
close( handle );
return( 0 );
}
Так як в MS-DOS відсутнє право доступу “тільки запис”, створення файлу з правами S_IWRITE дозволяє і читання файлу. Але функція creat() зазнає невдачі, якщо створюваний файл вже існує і має атрибут “тільки для читання”, “системний” або “що приховується”.
![]() |
![]() |
![]() |