Опубликован: 15.06.2004 | Доступ: свободный | Студентов: 2557 / 712 | Оценка: 4.35 / 3.96 | Длительность: 27:47:00
ISBN: 978-5-9556-0011-6
Лекция 4:

Организация файловой системы

Выше мы отмечали, что, как правило, файлы создаются по мере необходимости при выполнении определенных операций. Одной из таких операций является копирование файлов, выполняемое служебной программой cp:

cp  [-fip] исходный_файл целевой_файл
cp  [-fip] исходный_файл ... целевой_каталог
cp  -R [-H | -L | -P] [-fip] исходный_файл 
    ... целевой_каталог

В двух первых формах утилита cp напоминает ln, только наряду с возможным созданием новых ссылок создаются и новые файлы и, в любом случае, копируется содержимое исходных (или указуемых исходными, если последние представляют собой символьные ссылки ) файлов.

При наличии опции -R выполняется рекурсивное копирование исходных файловых иерархий в целевой каталог со стандартной трактовкой символьных ссылок, управляемой опциями -H, -L и -P (см. выше, например, описание утилиты chown ). Если копирование производится в существующий каталог, имена копий образуются как конкатенация целевого каталога, символа / и маршрута относительно каталога, содержащего исходный_файл. Если в командной строке заданы два файла и целевой не существует, он создается и становится корнем иерархии-копии, то есть исходный_файл копируется непосредственно в него, а маршруты файлов нижележащих уровней считаются относительно исходного_файла.

Если в командной строке задано более двух файлов и целевой не существует или не является каталогом, это считается ошибкой.

Опция -i влечет запрос подтверждения перед попыткой копирования в существующий файл.

По опции -f, если не удается открыть целевой файл, делается попытка сначала удалить его, а затем продолжить действия по копированию.

Опция -P вызывает копирование не только содержимого, но и атрибутов исходных файлов ( режима, идентификаторов владельца и владеющей группы, времени последнего доступа и изменения).

Синтаксис, с точностью до опций аналогичный двум первым формам cp, имеет вызов служебной программы перемещения файлов   mv:

mv  [-fi] исходный_файл целевой_файл mv  
    [-fi] исходный_файл ... 
	существующий_целевой каталог

Формально можно считать, что она выполняет копирование иерархий с корнями в исходных_файлах (без раскрытия символьных ссылок и с копированием атрибутов файлов) и уничтожает оригиналы. Отметим, что в первой форме mv целевой_ файл может не существовать, а исходный - являться каталогом ; в любом случае на месте целевого каталога допускается использование символьной ссылки на него.

На самом деле утилита mv, как правило, применяется для переименования файлов, и тогда ее работа сводится к созданию новых элементов каталогов и уничтожению старых, а реальное копирование может потребоваться только при перемещении файлов между файловыми системами (например, со съемного носителя на постоянный).

По опции -i   запрашивается подтверждение перед замещением существующего файла, опция -f влечет отсутствие подобных запросов (по поводу логики запроса подтверждений см. выше описание команды rm ).

Приведем пример употребления утилиты mv. Пусть текущий каталог содержит только файлы   x и y и пустой каталог   d1 (см. листинг 4.43). Тогда после выполнения команд, показанных в листинге 4.44, будет создан каталог   d2, где окажутся файлы   x и y, а каталог   d1 исчезнет (см. листинг 4.45).

.: d1/  x  y
./d1:
Листинг 4.43. Состояние текущего каталога перед перемещением файлов.
ls -RF
mv x y d1
mv d1 d2
ls -RF
Листинг 4.44. Использование утилиты mv для перемещения файлов и файловых иерархий.
.:
d2/
./d2:
x  y
Листинг 4.45. Состояние текущего каталога после перемещения файлов.

Продолжим этот пример двумя одинаковыми командами копирования (см. листинг 4.46).

cp -R d2 d1
cp -R d2 d1
ls -RF
Листинг 4.46. Применение утилиты cp для копирования файловых иерархий.

Первая команда скопирует иерархию с корнем d2 во вновь созданный каталог   d1, вторая - под d1 (с сохранением имени d2 для корня копии). Результат показан в листинге 4.47.

.:
d1/  d2/
./d1:
d2/  x  y
./d1/d2:
x  y
./d2:
x  y
Листинг 4.47. Результат использования утилиты cp для копирования файловых иерархий.

Для перемещения (переименования) одного файла служит функция rename() из репертуара C99 (см. листинг 4.48).

#include <stdio.h>
int rename (const char *old_path, 
            const char *new_path);
Листинг 4.48. Описание функции rename().

Функция rename() обладает частью функциональности служебной программы mv. Она не перемещает файловых иерархий и не раскрывает символьных ссылок, если их имена заданы в качестве аргументов. С другой стороны, rename() поддерживает переименование каталогов. В этом случае аргумент new_path не должен задавать файл другого типа, а если он задает существующий каталог, тот, по понятным причинам, должен быть пустым.

В продолжение двух предыдущих примеров продемонстрируем переименование каталогов (см. листинг 4.49). Итоговое состояние текущего каталога показано в листинге 4.50.

#include <stdlib.h>
#include <stdio.h>
#define OLD_DIR "d1/d2"
#define NEW_DIR "d2"
int main (void) {
 system ("rm -f " NEW_DIR "/*");
 if (rename (OLD_DIR, NEW_DIR)) {
   perror ("RENAME failed");
   return (-1);
 }
 system ("ls -RF");
 return 0;
}
Листинг 4.49. Пример использования функции rename() для переименования каталогов.
.:
d1/  d2/
./d1:
x  y
./d2:
x  y
Листинг 4.50. Состояние текущего каталога после переименования каталогов с помощью функции rename().

Читателю предлагается оценить последствия повторного запуска приведенной программы.

Антон Коновалов
Антон Коновалов

В настоящее время актуальный стандарт - это POSIX 2008 и его дополнение POSIX 1003.13
Планируется ли актуализация материалов данного очень полезного курса?