Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
PR_СП_лекции_укр.doc
Скачиваний:
6
Добавлен:
22.04.2019
Размер:
697.34 Кб
Скачать

2.5.4 Системні виклики truncate і ftruncate

truncate — змінює розмір файлу, заданого по імені

#include <unistd.h>

#include <sys/types.h>

int truncate(const char *path, off_t length );

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

Length - новий розмір файлу

Повертає 0 у разі успіху -1 у разі помилки (код помилки -в змінної errno)

ftruncate — змінює розмір файлу, заданого дескриптором

#include <unistd.h>

#include <sys/types.h>

int ftruncate(int fd, off_t length);

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

length - новий розмір файлу

Повертає 0 у разі успіху -1 у разі помилки (код помилки -в змінної errno)

Системні виклики truncate і ftruncate використовуються для зміни розмірів файлу як у велику, так і в меншу сторону. Як можна збільшити розмір файлу без фактичного запису даних в нього, вже розповідалося, при обговоренні системного виклику lseek. Хоча truncate і ftruncate можуть збільшувати розмір файлу, все ж таки частіше вони використовуються для зменшення (усікання) файлів. Раніше, до появи цих викликів в UNIX, усікання файлів було неможливим. (Доводилося створювати новий файл і потім перейменовувати його.)

2.6 Управління каталогами

2.6.1 Створення і видалення

mkdir() створює порожній каталог

#include <sys/types.h>

#include <sys/stat.h>

int mkdir(const char *pathname, mode_t mode);

Return: 0 якщо OK -1 при помилці

Ця функція створює новий порожній каталог. Елементи крапка і крапка-крапка створюються автоматично. Вказані права доступу до файлів, mode, модифікується маскою створення файлів процесу. Загальна помилка - указувати такий же режим має рацію як і для файлу (тільки читання і запис). Але для директорія нам треба, по украй мірі, підняти один біт виконання, щоб дістати доступ до імен файлів усередині директорія.

rmdir() видаляє порожній каталог

#include <unistd.h>

int rmdir(const char *pathname);

Return: 0, якщо все OK -1 при помилці

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

2.6.2 Читання каталога

Каталог може бути прочитаний будь-яким користувачем у кого є права для читання каталога. Але здійснити запис в каталог може тільки ядро (для збереження працездатності файлової системи).

Стандартна бібліотека Linux надає два способи перерахування вмісту директорій:

  1. за допомогою функції scandir() і функцій зворотного виклику

int scandir (const char *dir, struct dirent ***namelist,

int(*select)(const struct dirent *)

int(*compar)(const struct dirent **, const struct dirent **));

Як функція сортування запропоновані alphasort() і versionsort(), а ось фільтр, так розумію, потрібно писати свій.

Функція scandir() повертає кількість обраних записів або -1, якщо трапилася помилка.

  1. другий – з використанням набору функцій opendir(), readdir(), closedir().

#include <sys/types.h>

#include <dirent.h>

DIR * opendir(const char *pathname);

Return: покажчик, якщо все OK, NULL при помилці

struct dirent *readdir(DIR *dp);

Return: покажчик, якщо все OK, NULL якщо кінець каталога або помилка

void rewinddir(DIR *dp);

int closedir(DIR *dp);

Return: 0, якщо все OK -1 при помилці

Структура dirent визначена у файлі <dirent.h> і є залежною від реалізації. Але вона містить по украй мірі два елементи.

struct dirent {

int_t d_ino; // номер I-node

char d_name[NAME_MAX+1]; // ім'я файлу

}

Константа NAME_MAX залежить від файлової системи в якій розміщується каталог і її значення береться з функції fpathconf(). Часте значення для BSD-систем складає 255.

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

Розглянемо два варіанти програми printdir, що роздруковує вміст директорії, переданої їй як аргумент.

#include <stdio.h>

#include <dirent.h>

int sel(struct dirent * d)

{ return 1; // завжди підтверджуємо}

int main(int argc, char ** argv){

int i, n;

struct dirent ** entry;

if (argc != 2)

{

printf("Використання: %s <директория>\n", argv[0]);

return 0;

}

n = scandir(argv[1] &entry, sel, alphasort);

if (n < 0)

{

printf("Помилка читання директории\n");

return 1;

}

for (i = 0; i < n; i++)

printf("%s inode=%i\n", entry[i]->d_name, entry[i]->d_ino);

return 0;

}

Функція scandir() створює список елементів вказаної директорії. Їй необхідно передати покажчик на функцію-фільтр, яка, отримуючи дані про черговий елемент, ухвалює рішення, включати цей елемент в результуючий список. У нашому прикладі це функція sel(). Якщо при черговому виклику функція sel() поверне значення 0, відповідний елемент директорії не буде включений в кінцевий список. Останній параметр scandir - функція сортування елементів директорії. Ми використовуємо функцію alphasort(), що сортує елементи в лексикографічному порядку.

Дані про елементи директорії передаються в структурах dirent. Можна було б чекати, що структури типу dirent містять багато корисної інформації про елементи директорії, але це не так. Окрім імені файлу dirent містить номер inode для цього елементу (простим програмам зазвичай не навіщо знати номера inode, але, щоб наш приклад якось відрізнявся від стандартного, ми включаємо цю інформацію). У структури dirent є ще поле d_type типу char *, але воно, як правило, містить null.

Функція scandir() дозволяє нам отримати повний відсортований список елементів директорії за один виклик. У нас є можливість використовувати низькорівневі засоби, які можуть опинитися швидше в тому випадку, якщо сортування файлів нам не потрібне.

Розглянемо другий варіант програми:

#include <stdio.h>

#include <dirent.h>

int main(int argc, char ** argv)

{

DIR * d;

struct dirent * entry;

if (argc != 2)

{

printf("Використання: %s <директория>\n", argv[0]);

return 0;

}

d = opendir(argv[1]);

if (d == NULL)

{

printf("Помилка читання директории\n");

return 1;

}

while (entry = readdir(d))

printf("%s inode=%i\n", entry->d_name, entry->d_ino);

closedir(d);

return 0;

}

Цей варіант програми використовує функції opendir(), readdir() і closedir(), які працюють з директорією як з файлом. Функція readdir() повертає значення TRUE до тих пір, поки не будуть прочитані всі елементи директорії.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]