Інтерфейси для файлового введення / виводу



У середовищі програмування UNIX існують два основних інтерфейсу для файлового введення / виводу:

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

2. Стандартна бібліотека вводу / виводу, що пропонує функції буферізірованний введення / виводу.

 

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

 

Кожен системний виклик - це звернення до ядра операційної системи. Це викликає ряд проблем:

− доступ до диска (читання / запис) набагато (на кілька порядків) повільніше, ніж доступ до даних в оперативній пам'яті,

− при зверненні до ядра відбувається досить велика додаткова робота, яка може значно перевищити корисну роботу,

− системні виклики працюють з файлом як з неструктурованим масивом байт; тоді як зручніше представляти, що файл поділений на рядки.

 

Основна відмінність між підпрограмою і системним викликом полягає в тому, що при виклику підпрограми виконуваний код є частиною об'єктного коду програми, навіть якщо він був скомпонований з бібліотеки; при системному виклику основна частина виконуваного коду в дійсності є частиною ядра, а не викликає програми. Іншими словами, викликає програма безпосередньо викликає кошти, що надаються ядром. Переключення між ядром і призначеним для користувача процесом зазвичай здійснюється за допомогою механізму програмних переривань.

 

Системний виклик відбувається в 2 етапи:

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

2. Реакція ядра на переривання:

− перехід в привілейований режим;

− з'ясування, ХТО звернувся до ядра, і переключення контексту відповідного процесу;

− витяг аргументів з пам'яті запросила процесу;

− з'ясування, ЩО ж хочуть від ядра (один з аргументів, невидимий нам - це номер системного виклику);

− перевірка коректності інших аргументів;

− перевірка прав процесу на допустимість виконання такого запиту;

− виклик тіла необхідного системного виклику - це звичайна Сі-функція в ядрі;

− повернення відповіді в пам'ять процесу;

− вимикання привілейованого режиму;

− повернення з переривання.

 

Системні виклики роботи з файлами

При програмуванні операцій з файлами мовою Си використовуються бібліотечні виклики мови орієнтовані в першу чергу на операційну систему Unix (для якої мова й розроблявся).

 

Прототипи необхідних для роботи з файлами функцій, використовувані при цьому типи й константи описані в заголовних файлах:

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

 

Для роботи з файлами використовуються наступні функції.

 

Відкриття файлу виконується по функції

int open(const char *path, int flags, mode_t mode);

 

де перший параметр задає ім'я файлу, другий параметр показує, які види доступу до файлу дозволені зухвалому процесу.

 

Параметр flags може приймати наступні значення:

O_RDONLY - відкриття файлу тільки для читання;

O_WRONLY - відкриття файлу тільки для запису;

O_RDWR - відкриття файлу для читання й запису.

 

Значення параметра може логічно складатися з модифікаторми:

O_APPEND - дані додаються в кінець файлу;

O_CREAT - створюється файл, якщо він не існує;

O_TRUNC - якщо файл існує, то його вміст губиться, а розмір

установлюється рівним 0;

O_EXCL - використовується разом із прапором O_CREAT, у

цьому випадку спроба створити файл, якщо він уже

існує, кінчається невдачею.

 

Параметр mode установлює атрибути прав доступу різних категорій користувачів до нового файлу при його створенні. Він обов'язковий, якщо серед заданих прапорів присутній прапор O_CREAT, і може бути опущений у противному випадку. Цей параметр задається як сума наступних восьмеричних значень:

 

0400 - дозволене читання для користувача, що створив файл;

0200 - дозволений запис для користувача, що створив файл;

0100 - дозволене виконання для користувача, що створив файл;

0040 - дозволене читання для групи користувача, що створив файл;

0020 - дозволений запис для групи користувача, що створив файл;

0010 - дозволене виконання для групи користувача, що створив файл;

0004 - дозволене читання для всіх інших користувачів;

0002 - дозволений запис для всіх інших користувачів;

0001 - дозволене виконання для всіх інших користувачів.

 

У стандарті POSIX Ці коди мають ще й мнемонічні імена (використовувані у виклику stat):

Принцип їхнього іменування треба шаблону S_Ipwww, де p визначає режим доступу (R, w або X), a www — кому видається право на цей режим доступу (USR, GRP або OTH).

Наприклад, для восьмеричного числа 755 можна записати:

S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH

 

Існують окремі ідентифікатори для USR, GRP і OTH, які описують повні права доступу. Іменування цих ідентифікаторів треба формі S_IRWXw. Тут символ w визначає, кому видається повне право доступу до файлу (від англ, «whom» - «кому») - U, G або О. Таким чином, що предыдет приклад може бути записаний у наступному виді:

S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH

 

Використання ідентифікаторів дає розроблювачам ОС волю вибору порядку проходження біт, що описують права доступу до файлу.

 

mode завжди повинен бути зазначений при використанні O_CREAT, у всіх інших випадках цей параметр ігнорується.

 

При створенні файлу реально встановлюваного права доступу виходять зі стандартної комбінації параметра mode і маски створення файлів поточного процесу umask, а саме - вони рівні mode & umask.

 

Маска звичайно встановлюється під час реєстрації користувача в системі (командою umask) або системним викликом umask. Фраза «логічне множення на логічне доповнення» означає: якщо якийсь біт маски встановлений, те відповідний йому біт в остаточному наборі прав доступу скидається.

Після успішного відкриття файлу функція повертає значення дескриптора файлу.

 

Створення файлу.

Виклик creat - це просто різновид виклику open у формі

d=open(ім'я_файлу,O_WRONLY|O_TRUNC|O_CREAT,mode);

 

creat - створює новий або очищає існуючий файл і відкриває його на запис

 

#include <sys/stat.h>

#include <sys/types.h>

#include <fcntl.h>

int creat(const char *path, mode_t perms)

 

path - повне ім'я файлу

perms - права доступу

Повертає дескриптор файлу або -1 у випадку помилки

 

Читання даних виконується з використанням функцій з бібліотеки мови Си. Зокрема, для читання можна використовувати функцію:

ssize_t read(int fdes, char *buf, size_t count);

Запис у файл може виконуватися по функції:

ssize_t write(int fdes, char *buf, size_t count);

 

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

Закривається файл функцією

int close(int fdes);

аргументом функції є дескриптор відповідного файлу.

 

Позіціонуваня у файлі

 

Системний виклик lseek використовується для переустановлення поточної позиції у файлі. Він не виконує ніяких операцій введення-виводу і не віддає команд контроллеру диска.

 

#include <sys/types.h>

#include <unistd.h>

off_t lseek( int fd, off_t offset, int whence );

 

fd - дескриптор файлу

pos - позиція у файлі

whence - інтерпретація аргументу pos

Повертає нову позицію у файлі або -1 у разі помилки (код помилки в змінній errno)

 

Аргумент whence може приймати одне з наступних значень:

SEEK_SET Аргумент pos містить зсув від початку файлу (абсолютна позиція у файлі).

SEEK_CUR Аргумент pos містить зсув від поточної позиції у файлі. Може бути позитивним числом, нулем і негативним числом. Вказавши в аргументі pos значення 0 — ми отримаємо поточну позицію у файлі.

SEEK_ENO Аргумент pos містить зсув від кінця файлу. Може бути позитивним числом, нулем і негативним числом. Вказавши в аргументі pos значення 0 — ми встановимо поточну позицію в кінець файлу.

 

Результатом роботи виклику може бути будь-яке ненегативне число, що навіть перевищує розмір файлу. Якщо нова поточна позиція опинилася за межами файлу, то найближчий виклик write вставить «бракуючий» шматок в кінець файлу і заповнить його байтами із значенням 0. Виклик read, з поточною позицією встановленою в кінець файлу або за його межами, поверне ознаку кінця файлу — 0. Спроба читання з інтервалу, який заповнив виклик write при вставці «бракуючого» шматка, увінчається успіхом і в зухвалу програму буде повернений буфер, заповнений нулями, як того і слід було чекати.

 

 

Приклад - копіювання даних з одного файлу в новий файл.

 

#include <stdio.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <errno.h>

#include <unistd.h>

int main() {

int fdIn; //Вхідний файл

int fdOut; //Вихідний файл

char buf[256]; //Буфер обміну

char InName[20], OutName[20]; //Імена файлів

ssize_t nRd;

 

// Уведення імен вхідного й вихідного файлів

printf("Ім'я вхідного файлу -> ");

gets(InName);

printf("Ім'я вихідного файлу -> ");

gets(OutName);

 

 // Відкриття файлів

if((fdIn=open(InName, O_RDONLY))==-1)

{perror("Помилка відкриття вхідного файлу"); exit(-1);}

if((fdOut=open(OutName, O_WRONLY|O_CREAT,644))==-1)

 { perror("Помилка відкриття вихідного файлу"); close(fdIn);

  exit(-2); }

 

 // Цикл копіювання

while((nRd=read(fdIn, buf, 256))>0)

{ if(write(fdOut, buf, nRd)<nRd)

 { perror("Помилка запису"); close(fdIn); close(fdOut); exit(-3); }

}

close(fdIn); close(fdOut);

printf("Завершення програми\n"); exit(0);

 }

 

При відкритті вхідного файлу задається ключ режиму роботи з файлом "тільки для читання" (O_RDONLY). Функція повертає дескриптор відкритого файлу. У випадку помилки вертається -1. Для висновку повідомлення про помилку використовується функція perror(). Ця функція виводить задається їй як аргумент текст. Крім того, функція обробляє системний номер помилки (errno) і додає у виведений рядок системне повідомлення про помилку.

Функція, що відкриває вихідний файл повертає дескриптор вихідного файлу. Ця функція виконується з режимами "тільки для запису" (O_WRONLY) і із ключем створення нового файлу (O_CREAT). Крім цього, при виклику функції використовується третій параметр (644), що визначає права доступу до створюваного файлу (читання й запис для власника й тільки читання для інших користувачів).

 

Індівідуальні завдання

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

Варіанти завдань


Дата добавления: 2018-04-05; просмотров: 391; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!