Molte cose sono cambiate in 8 anni.
Fallocazione
fallocate -d
filename
può essere utilizzato per perforare i file esistenti. Dal fallocate(1)
pagina man:
-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.
(Quella lista:)
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 in quella lista è quello che trovo più interessante. Il filesystem stesso è abbastanza efficiente da consumare solo la quantità di RAM necessaria per archiviare i suoi contenuti, ma rendendo i contenuti sparse può potenzialmente aumentare ulteriormente tale efficienza.
GNU cp
Inoltre, da qualche parte lungo la strada GNU cp
acquisito una comprensione dei file sparsi. Citando il cp(1)
pagina man riguardante la sua modalità predefinita, --sparse=auto
:
i file SOURCE sparsi vengono rilevati da un'euristica grezza e anche il file DEST corrispondente viene reso scarso.
Ma c'è anche --sparse=always
, che attiva l'equivalente in copia file di quanto fallocate -d
esegue sul posto:
Specifica
--sparse=always
per creare un file DEST sparse ogni volta che il file SOURCE contiene una sequenza sufficientemente lunga di zero byte.
Finalmente sono riuscito a ritirare il mio tar cpSf - SOURCE | (cd DESTDIR && tar xpSf -)
one-liner, che per 20 anni è stato il mio modo da barba grigia di copiare file sparsi preservando la loro scarsità.
Alcuni filesystem su Linux / UNIX hanno la capacità di "perforare" un file esistente. Vedi:
- Post LKML sulla funzione
- Domande frequenti sul troncamento dei file UNIX (cercare F_FREESP)
Non è molto portatile e non è fatto allo stesso modo su tutta la linea; al momento, credo che le librerie IO di Java non forniscano un'interfaccia per questo.
Se la perforazione è disponibile tramite fcntl(F_FREESP)
o tramite qualsiasi altro meccanismo, dovrebbe essere significativamente più veloce di un ciclo di copia/ricerca.
Penso che faresti meglio a pre-allocare l'intero file e mantenere una tabella/BitSet delle pagine/sezioni che sono occupate.
La creazione di un file sparse comporterebbe la frammentazione di tali sezioni se mai fossero riutilizzate. Forse il risparmio di pochi TB di spazio su disco non vale il calo delle prestazioni di un file altamente frammentato.