Beaucoup de choses ont changé en 8 ans.
Fallocer
fallocate -d
filename
peut être utilisé pour percer des trous dans des fichiers existants. A partir du fallocate(1)
page de manuel :
-d, --dig-holes
Detect and dig holes. This makes the file sparse in-place,
without using extra disk space. The minimum size of the hole
depends on filesystem I/O block size (usually 4096 bytes).
Also, when using this option, --keep-size is implied. If no
range is specified by --offset and --length, then the entire
file is analyzed for holes.
You can think of this option as doing a "cp --sparse" and then
renaming the destination file to the original, without the
need for extra disk space.
See --punch-hole for a list of supported filesystems.
(Cette liste :)
Supported for XFS (since Linux 2.6.38), ext4 (since Linux
3.0), Btrfs (since Linux 3.7) and tmpfs (since Linux 3.5).
tmpfs étant sur cette liste est celui que je trouve le plus intéressant. Le système de fichiers lui-même est suffisamment efficace pour ne consommer que la quantité de RAM dont il a besoin pour stocker son contenu, mais en rendant le contenu sparse peut potentiellement augmenter encore plus cette efficacité.
GNU cp
De plus, quelque part en cours de route GNU cp
acquis une compréhension des fichiers clairsemés. Citant le cp(1)
page de manuel concernant son mode par défaut, --sparse=auto
:
les fichiers SOURCE clairsemés sont détectés par une heuristique grossière et le fichier DEST correspondant est également rendu clairsemé.
Mais il y a aussi --sparse=always
, qui active l'équivalent de copie de fichier de ce que fallocate -d
fait sur place :
Spécifiez
--sparse=always
pour créer un fichier DEST clairsemé chaque fois que le fichier SOURCE contient une séquence suffisamment longue de zéro octet.
J'ai enfin pu retirer mon tar cpSf - SOURCE | (cd DESTDIR && tar xpSf -)
one-liner, qui pendant 20 ans a été ma façon à la barbe grise de copier des fichiers clairsemés en préservant leur rareté.
Certains systèmes de fichiers sous Linux / UNIX ont la capacité de "percer des trous" dans un fichier existant. Voir :
- Publication LKML sur la fonctionnalité
- FAQ sur la troncature de fichiers UNIX (recherchez F_FREESP)
Ce n'est pas très portable et ce n'est pas fait de la même manière à tous les niveaux; pour le moment, je pense que les bibliothèques d'E/S de Java ne fournissent pas d'interface pour cela.
Si la perforation est disponible via fcntl(F_FREESP)
ou via tout autre mécanisme, cela devrait être beaucoup plus rapide qu'une boucle de copie/recherche.
Je pense que vous feriez mieux de pré-allouer l'ensemble du fichier et de maintenir une table/BitSet des pages/sections qui sont occupées.
Faire un fichier clairsemé entraînerait la fragmentation de ces sections si jamais elles étaient réutilisées. Peut-être que l'économie de quelques To d'espace disque ne vaut pas le coup de performance d'un fichier très fragmenté.