Domanda

Se ho un grande file contenente molti zeri, come posso renderlo in modo efficiente un file sparso?

L'unica possibilità di leggere l'intero file (compresi tutti gli zero, che può essere passivamente archiviato scarsamente) e di riscriverlo in un nuovo file utilizzando Seek per saltare le aree zero?

O esiste la possibilità di realizzarlo in un file esistente (ad es. File.setsparse (a lungo inizio, end a lungo))?

Sto cercando una soluzione in Java o in alcuni comandi Linux, il filesystem sarà EXT3 o simile.

È stato utile?

Soluzione

Alcuni filesystem su Linux / UNIX hanno la possibilità di "dare il pugno" in un file esistente. Vedere:

Non è molto portatile e non fatto allo stesso modo su tutta la linea; A partire da ora, credo che le librerie IO di Java non forniscano un'interfaccia per questo.

Se è disponibile un pugno di foro tramite fcntl(F_FREESP) o tramite qualsiasi altro meccanismo, dovrebbe essere significativamente più veloce di un ciclo di copia/ricerca.

Altri suggerimenti

Molto è cambiato in 8 anni.

Fallosate

fallocate -dfilename può essere utilizzato per punzonare i fori nei file esistenti. Dal fallocate(1) Pagina uomo:

       -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 Essere in quella lista è quello che trovo più interessante. Il filesystem stesso è abbastanza efficiente da consumare solo tutta la RAM che deve archiviare il suo contenuto, ma realizzare il Contenuti Sparse può potenzialmente aumentare ulteriormente tale efficienza.

GNU cp

Inoltre, da qualche parte lungo la strada GNU cp ha acquisito una comprensione dei file sparsi. Citando il cp(1) Pagina uomo Per quanto riguarda la sua modalità predefinita, --sparse=auto:

I file di origine sparsa vengono rilevati da un euristico greggio e anche il file DEST corrispondente viene reso scarso.

Ma c'è anche --sparse=always, che attiva l'equivalente del file-copy di cosa fallocate -d fa sul posto:

Specificare --sparse=always Per creare un file DEST sparso ogni volta che il file di origine contiene una sequenza abbastanza lunga di zero byte.

Sono stato finalmente in grado di ritirare il mio tar cpSf - SOURCE | (cd DESTDIR && tar xpSf -) One-liner, che per 20 anni è stato il mio modo di Grayberd di copiare file sparsi con la loro scarsità conservata.

Penso che starai meglio pre-allocare l'intero file e mantenere una tabella/bitset delle pagine/sezioni occupate.

Fare un file sparso comporterebbe frammenti di quelle sezioni se fossero mai state riutilizzate. Forse il salvataggio di alcuni TB di spazio su disco non vale il colpo di prestazione di un file altamente frammentato.

Secondo questo articolo, sembra che attualmente non ci sia soluzione facile, tranne per l'uso di FIEMAP IOCTL. Tuttavia, non so come puoi rendere zero blocchi "non sparsi" in quelli "sparsi".

Puoi usare $ truncate -s filename filesize su Linux teminal per creare file sparsi

Solo metadati.

Nota: il filesize è in byte.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top