Les interfaces d'appel système typiques permettent-elles de réduire la taille d'un fichier (sans le remplacer par un autre inode)?

9

Existe-t-il un moyen d'accéder à open()un fichier et de le réduire? On peut, bien sûr, les ouvrir en mode ajout ou chercher à la fin et écrire pour les faire grandir. Cependant, pour autant que je sache, il n'existe aucune méthode pour réduire un fichier via des interfaces d'appel système de style Unix typiques.

Pour autant que je sache, la seule façon de le faire est de le simuler en créant un nouveau fichier plus court et rename()à la place de l'ancien.

Je voulais juste une confirmation, car j'ai vu une réponse qui impliquait qu'il était possible de créer des éditeurs de fichiers qui travaillaient directement sur un fichier au lieu de passer par le processus de création d'un nouveau et de le renommer en place.

J'ai toujours pensé que l'API de fichier dans les interfaces d'appel système de style libc et unix ne permettait pas la réduction des fichiers pour faciliter l'implémentation des systèmes de fichiers et peut-être éviter les modèles d'utilisation qui pourraient contribuer à la fragmentation.

JoL
la source
2
Le simple fait d'ouvrir un fichier fopenen mode "w" (ou "w +") le tronquera automatiquement à zéro. Ou voulez-vous dire de réduire à une taille non nulle, pour préserver certains des anciens contenus?
Wyzard
4
Juste FYI, open()et openat()ont déjà un indicateur pour tronquer, O_TRUNCdonc techniquement cela fait rétrécir le fichier - c'est-à-dire rétrécir complètement - sans changer d'inode. L'exemple le plus célèbre est celui command > file.txtoù le fichier sera tronqué s'il existe. Si vous exécutez strace, bash -c 'true > /dev/null'vous verrez openat(AT_FDCWD, "/dev/null", O_WRONLY|O_CREAT|O_TRUNC, 0666)dans la sortie. Bien sûr, pour une taille de troncature variable, vous avez besoin d'un truncate()appel système. Faites-moi savoir si vous voulez que ce soit une réponse réelle au lieu du commentaire.
Sergiy Kolodyazhnyy
@SergiyKolodyazhnyy Je pensais à une taille arbitraire. J'ai surévalué la réponse de David Foerster parce qu'elle répond à un sous-ensemble de la question, mais je ne l'accepte pas à la lumière de celle d'Icare. Je l'aurais considéré comme une réponse de type oui et non, alors que la réponse d'icarus a déjà montré que la vraie réponse est un "oui".
JoL

Réponses:

22

man -s 2 ftruncate dit

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).

il ajoute que si vous utilisez ftruncate, vous devez avoir ouvert le fichier pour l'écriture, et si vous utilisez truncate, le fichier doit être accessible en écriture.

icare
la source
L'ajout à un fichier oblige le système d'exploitation à truncates'adapter à la nouvelle taille de fichier, puis à write lui. Il en truncateva de même pour l'appel système que vous recherchez.
mgarciaisaia
1
Sur Linux, voir aussifallocate(FALLOC_FL_COLLAPSE_RANGE)
Stéphane Chazelas
2

L' open(2)appel système accepte l' O_TRUNCindicateur qui peut réduire la taille du fichier:

O_TRUNC- Si le fichier existe et est un fichier normal, et que le fichier est ouvert avec succès O_RDWRou O_WRONLY, sa longueur doit être tronquée à 0, et le mode et le propriétaire doivent être inchangés. Il n'aura aucun effet sur les fichiers spéciaux FIFO ou les fichiers de terminal. Son effet sur d'autres types de fichiers est défini par l'implémentation. Le résultat de l'utilisation O_TRUNCsans O_RDWRou O_WRONLYnon n'est pas défini.

Il est fréquemment utilisé lorsque le programme vise à remplacer entièrement le contenu d'un fichier. Un exemple est l'opérateur de redirection de fichiers de votre shell comme dans command > file.

David Foerster
la source