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


9

Чи є спосіб, щоб open()файл і змусив його скорочуватися? Можна, звичайно, відкривати їх у додатку або шукати до кінця та писати, щоб вони зростали. Однак, наскільки я знаю, немає способу зменшити файл через типові інтерфейси системного виклику в стилі Unix.

Наскільки я знаю, єдиний спосіб зробити це підробкою, створивши новий коротший файл і rename()замість старого.

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

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


2
Просто відкриваємо файл із fopen в режимі "w" (або "w +") автоматично скоротить його до нульової довжини. Або ви маєте на увазі скорочення до ненульового розміру, щоб зберегти частину старого вмісту?
Wyzard

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()syscall. Дайте мені знати, чи хочете ви це як фактичну відповідь замість коментаря.
Сергій Колодяжний,

@SergiyKolodyazhnyy Я думав зменшити довільний розмір. Я підтримав відповідь Девіда Фоерстера, оскільки він відповідає на підмножину питання, але я не приймаю його з огляду на ікарус. Я би сприйняв це як відповідь "ні", тоді як відповідь ікаруса вже показав, що справжня відповідь - "так".
ДжоЛ

Відповіді:


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нового розміру файлу, а потім - до 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.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.