Позволяют ли типичные интерфейсы системных вызовов уменьшить размер файла (не заменяя его другим индексом)?

9

Есть ли способ для open()файла и вызвать его сжатие? Можно, конечно, открыть их в режиме добавления или искать до конца и написать, чтобы они росли. Однако, насколько я знаю, нет способа сжать файл через типичные интерфейсы системных вызовов в стиле Unix.

Насколько я знаю, единственный способ сделать это - подделать его, создав новый более короткий файл, а rename()не старый.

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

Я всегда думал, что файловый интерфейс API в интерфейсах системных вызовов в стиле libc и unix не позволяет уменьшить файлы, чтобы упростить реализацию файловых систем и, возможно, избежать использования моделей, которые могут способствовать фрагментации.

Йол
источник
2
Простое открытие файла fopenв режиме «w» (или «w +») автоматически обрезает его до нулевой длины. Или вы имеете в виду сокращение до ненулевого размера, чтобы сохранить часть старого содержимого?
Вайзард
4
Просто FYI, open()и openat()уже есть флаг для усечения, O_TRUNCтак что технически это приводит к уменьшению файла - то есть к полному сокращению - без изменения inode. Самый известный пример того command > file.txt, где файл будет обрезан, если он существует. Если вы бежите straceна bash -c 'true > /dev/null'вас будут видеть openat(AT_FDCWD, "/dev/null", O_WRONLY|O_CREAT|O_TRUNC, 0666)на выходе. Конечно, для переменного размера усечения вам нужен truncate()системный вызов. Дайте мне знать, если вы хотите это как реальный ответ вместо комментария.
Сергей Колодяжный
@SergiyKolodyazhnyy Я думал о сокращении до произвольного размера. Я проголосовал за ответ Дэвида Фёрстера, потому что он отвечает на часть вопроса, но я не принимаю его в свете ответа Икара. Я бы воспринял это как ответ типа «да и нет», тогда как ответ Икара уже показал, что реальный ответ - «да».
JoL

Ответы:

22

man -s 2 ftruncate говорит

DESCRIPTION
   The  truncate()  and  ftruncate()  functions cause the regular file
   named by path or referenced by fd to be truncated to a size of precisely
   length bytes.

...

CONFORMING TO
   POSIX.1-2001, POSIX.1-2008, 4.4BSD, SVr4 (these calls first appeared in 4.2BSD).

далее говорится, что если вы используете ftruncate, вы, должно быть, открыли файл для записи, а если вы используете truncate, файл должен быть доступен для записи.

Икар
источник
Присоединение к файлу приводит к тому, что ОС сначала truncateучитывает новый размер файла, а затем - write его. Как truncateи системный вызов, который вы ищете.
mgarciaisaia
1
В Linux см. Такжеfallocate(FALLOC_FL_COLLAPSE_RANGE)
Стефан
2

open(2)Системный вызов принимает O_TRUNCфлаг , который может уменьшить размер файла:

O_TRUNC- Если файл существует и является обычным файлом, и файл успешно открыт O_RDWRили O_WRONLYего длина должна быть сокращена до 0, а режим и владелец не должны изменяться. Он не должен влиять на специальные файлы FIFO или файлы оконечного устройства. Его влияние на другие типы файлов определяется реализацией. Результат использования O_TRUNCбез O_RDWRили O_WRONLYне определен.

Он часто используется, когда программа стремится полностью перезаписать содержимое файла. Примером является оператор перенаправления файлов вашей оболочки, как в command > file.

Дэвид Фёрстер
источник