Comment rendre un fichier clairsemé ?
-
13-11-2019 - |
Question
Si j'ai un gros fichier contenant de nombreux zéros, comment puis-je en faire efficacement un fichier clairsemé ?
La seule possibilité est-elle de lire l'intégralité du fichier (y compris tous les zéros, qui peuvent être stockés de manière patrimoniale) et de le réécrire dans un nouveau fichier en utilisant la recherche pour ignorer les zones zéro ?
Ou existe-t-il une possibilité de faire cela dans un fichier existant (par ex.File.setSparse (début long, fin longue)) ?
Je recherche une solution en Java ou certaines commandes Linux, le système de fichiers sera ext3 ou similaire.
La solution
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 cela ne se fait pas de la même manière dans tous les domaines ;pour le moment, je pense que les bibliothèques IO 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.
Autres conseils
Beaucoup de choses ont changé en 8 ans.
Fallocate
fallocate -d
filename
peut être utilisé pour percer des trous dans des fichiers existants.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 ce qui rend le Contenu clairsemé peut potentiellement augmenter encore davantage cette efficacité.
GNOU 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écifier
--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 mettre mon tar cpSf - SOURCE | (cd DESTDIR && tar xpSf -)
one-liner, qui pendant 20 ans a été ma façon de copier des fichiers clairsemés avec leur rareté préservée.
Je pense que vous seriez mieux de pré-allouer tout le fichier et de maintenir une table / bitset des pages / sections occupées.
Faire un dossier clairsemé entraînerait la fragmentation de ces sections si elles ont été réutilisées.Sauvegarder peut-être que quelques tubercules d'espace disque ne valent pas la performance d'un fichier hautement fragmenté.
Selon ce Article , il semble qu'il n'y ait actuellement aucune solution facile, à l'exception de l'utilisation de FIMAP IOCTL.Cependant, je ne sais pas comment vous pouvez faire des blocs de zéro "non clairsemé" dans "clairsemé".
Vous pouvez utiliser $ truncate -s filename filesize
sur la borne Linux pour créer un fichier clairsemé avec
Seulement des métadonnées.
note --FileSize est en octets.