Crea rapidamente un file di grandi dimensioni su un sistema Linux


438

Come posso creare rapidamente un file di grandi dimensioni su un sistema Linux ( Red Hat Linux )?

dd farà il lavoro, ma leggere /dev/zeroe scrivere sull'unità può richiedere molto tempo quando è necessario un file di dimensioni diverse di centinaia di GB per il test ... Se è necessario farlo ripetutamente, il tempo si sommerà davvero.

Non mi interessa il contenuto del file, voglio solo che venga creato rapidamente. Come si può fare?

L'uso di un file sparse non funzionerà per questo. Ho bisogno che il file sia assegnato allo spazio su disco.


1
Ext4 ha prestazioni di allocazione dei file molto migliori, poiché è possibile allocare blocchi interi fino a 100 MB contemporaneamente.
martino

5
A proposito, il comando 'truncate' crea un file sparse. Ad esempio, vedi en.wikipedia.org/wiki/Sparse_file
Jason Drew

2
Le persone sembrano ignorare gravemente il "file sparso non funzionerà con questo", con le loro ricerche troncate e dd sotto.
hpavc,

1
Avresti dovuto definire cosa intendevi per "per i test". Testare la velocità di scrittura del tuo disco rigido? Test cosa dfsegnalerà? Test di un'app che fa qualcosa di particolare. La risposta dipende da cosa vuoi testare. Comunque sono un po 'in ritardo - vedo ora che sono passati anni dalla tua domanda :-)
ndemou

1
Nel caso in cui tu stia cercando un modo per simulare una partizione completa, come me, non cercare oltre / dev / full
Julian

Risposte:


509

dddalle altre risposte è una buona soluzione, ma è lento per questo scopo. In Linux (e altri sistemi POSIX), fallocateche utilizza lo spazio desiderato senza doverlo effettivamente scrivere, funziona con la maggior parte dei moderni file system basati su disco, molto velocemente:

Per esempio:

fallocate -l 10G gentoo_root.img

5
È possibile che dd lo stia già utilizzando internamente? Se faccio 'dd if = / dev / zero di = zerofile bs = 1G count = 1' su un kernel 3.0.0, la scrittura termina in 2 secondi, con una velocità di scrittura di oltre 500 megabyte al secondo. Questo è chiaramente impossibile su un hard disk per laptop da 2,5 ".
lxgr

21
fallocateè esattamente quello che stavo cercando.
AB,

7
Questo ( fallocate) non funzionerà anche su un filesystem Linux ZFS - github.com/zfsonlinux/zfs/issues/326
Joe

5
fallocate non è supportato neanche da ext3. bugzilla.redhat.com/show_bug.cgi?id=563492
Eddie

3
In Debian GNU / Linux fallocatefa parte del util-linuxpacchetto. Questo strumento è stato scritto da Karel Zak di RedHat e il codice sorgente può essere trovato qui: kernel.org/pub/linux/utils/util-linux
Franta

295

Questa è una domanda comune, specialmente nell'attuale ambiente di ambienti virtuali. Sfortunatamente, la risposta non è così semplice come si potrebbe presumere.

dd è la prima scelta ovvia, ma dd è essenzialmente una copia e questo ti costringe a scrivere ogni blocco di dati (quindi, inizializzando il contenuto del file) ... E quell'inizializzazione è ciò che richiede così tanto tempo di I / O. (Vuoi farla impiegare ancora più tempo? Usa / dev / random invece di / dev / zero ! Quindi userai CPU e tempo di I / O!) Alla fine però, dd è una scelta sbagliata (anche se essenzialmente il impostazione predefinita utilizzata dalla VM "crea" GUI). Per esempio:

dd if=/dev/zero of=./gentoo_root.img bs=4k iflag=fullblock,count_bytes count=10G

troncare è un'altra scelta - ed è probabilmente il più veloce ... Ma è perché crea un "file sparse". In sostanza, un file sparse è una sezione del disco che contiene molti degli stessi dati e il file system sottostante "imbroglia" non memorizzando realmente tutti i dati, ma semplicemente "fingendo" che sia tutto lì. Pertanto, quando si utilizza truncate per creare un'unità da 20 GB per la propria macchina virtuale, il file system non alloca effettivamente 20 GB, ma inganna e dice che ci sono 20 GB di zeri lì, anche se solo una traccia sul disco potrebbe effettivamente (davvero) essere in uso. Per esempio:

 truncate -s 10G gentoo_root.img

fallocate è l' ultima - e migliore - scelta per l'uso con allocazione del disco VM, perché è essenzialmente "riserve" (o "assegna" tutto lo spazio che stai cercando, ma non si preoccupa di nulla scrivere così,. quando usi fallocate per creare uno spazio su disco virtuale da 20 GB, ottieni davvero un file da 20 GB (non un "file sparse", e non ti preoccuperai di scrivere nulla su di esso - il che significa che praticamente tutto potrebbe essere dentro lì - un po 'come un nuovo disco!) Ad esempio:

fallocate -l 10G gentoo_root.img

4
+1 truncateè funzionale su JFS; fallocate, Non così tanto. Un punto: non puoi includere un numero decimale nel numero, dovevo specificare 1536G, no 1.5T.
Calrion,

1
Secondo la mia fallocatepagina man, questo è supportato solo su btrfs, ext4, ocfs2, e xfsfile system
Nathan S. Watson-Haigh

Nota swaponpurtroppo non funziona su estensioni pre-allocate, l'ultima volta che ho controllato. Ci sono state alcune discussioni sulla mailing list di XFS sull'avere un'opzione fallocate per esporre invece i vecchi dati dello spazio libero e non avere la misura contrassegnata come preallocata, quindi Swapon avrebbe funzionato. Ma non penso che sia mai stato fatto nulla.
Peter Cordes,

1
Cordiali saluti, il tentativo di leggere troppi dati da /dev/randompuò comportare l'esaurimento di dati casuali e "Quando il pool di entropia è vuoto, le letture da / dev / random si bloccano fino a quando non viene raccolto ulteriore rumore ambientale", quindi potrebbe richiedere molto molto tempo
Xen2050

154

Linux e tutti i filesystem

xfs_mkfile 10240m 10Gigfile

Linux e alcuni filesystem (ext4, xfs, btrfs e ocfs2)

fallocate -l 10G 10Gigfile

OS X, Solaris, SunOS e probabilmente altri UNIX

mkfile 10240m 10Gigfile

HP-UX

prealloc 10Gigfile 10737418240

Spiegazione

Prova mkfile <size>myfile in alternativa a dd. Con l' -nopzione si nota la dimensione, ma i blocchi del disco non vengono allocati fino a quando i dati non vengono scritti su di essi. Senza l' -nopzione, lo spazio è zero, il che significa scrivere sul disco, il che significa prendere tempo.

mkfile è derivato da SunOS e non è disponibile ovunque. La maggior parte dei sistemi Linux xfs_mkfilefunziona esattamente allo stesso modo, e non solo sui file system XFS nonostante il nome. È incluso in xfsprogs (per Debian / Ubuntu) o in pacchetti simili.

Anche la maggior parte dei sistemi Linux ha fallocate, che funziona solo su determinati file system (come btrfs, ext4, ocfs2 e xfs), ma è il più veloce, poiché alloca tutto lo spazio dei file (crea file non bucati) ma non inizializza alcun di esso.


5
Dov'è questo mkfile di cui parli, straniero? Non è presente nell'installazione RHEL predefinita.
paxdiablo,

2
È un'utilità Solaris. se cerchi gpl mkfile troverai alcuni esempi di codice sorgente.
Martin Beckett,

5
Funziona come un fascino su OS X:mkfile 1g DELETE_IF_LOW_ON_SSD_SPACE.img
Volker Rose

2
xfs_mkfileè incluso in xfsprogs su Ubuntu e funziona come un incantesimo sul mio ext3 fs. :)
Greg Dubicki,

97
truncate -s 10M output.file

creerà un file da 10 M istantaneamente (M sta per 1024 * 1024 byte, MB sta per 1000 * 1000 - lo stesso con K, KB, G, GB ...)

MODIFICARE: come molti hanno sottolineato, questo non alloca fisicamente il file sul tuo dispositivo. Con questo potresti effettivamente creare un file di grandi dimensioni arbitrario, indipendentemente dallo spazio disponibile sul dispositivo, in quanto crea un file "scarso".

Quindi, nel fare ciò, rimanderai l'allocazione fisica fino all'accesso al file. Se stai mappando questo file in memoria, potresti non avere le prestazioni previste.

Ma questo è ancora un comando utile da sapere


1
Ho provato questo, ma non influenza lo spazio disponibile su disco. È necessario perché è un file sparso come descritto in precedenza.
Gringo Suave,

7
Questa non dovrebbe essere la risposta migliore in quanto non risolve il problema, la fallocaterisposta qui sotto lo fa.
Gringo Suave,

4
@GringoSuave, ma questo è ancora utile per alcune persone che potrebbero avere un problema simile ma leggermente diverso.
AJMansfield,

@GringoSuave: sembra creare un file di grandi dimensioni come richiesto, perché non risolve il problema? Inoltre ci sono note sotto la risposta fallocate che nella maggior parte dei casi non funziona nemmeno.
Pavel Šimerda,

1
Perché suggerire di creare file sparsi quando ha detto che non funzionerà?
hpavc,

44

Dove cercare è la dimensione del file desiderato in byte - 1.

dd if=/dev/zero of=filename bs=1 count=1 seek=1048575

6
Mi piace questo approccio, ma il commentatore non vuole un file sparse per qualche motivo. :(
effimero

3
dd if = / dev / zero of = 1GBfile bs = 1000 count = 1000000
Damien

7
dd if = / dev / zero of = 01GBfile bs = 1024 count = $ ((1024 * 1024))
Xavier Decoret

1
Per i file sparsi, truncatesembra essere molto meglio.
Pavel Šimerda,

36

Esempi in cui seek è la dimensione del file desiderato in byte

#kilobytes
dd if=/dev/zero of=filename bs=1 count=0 seek=200K

#megabytes
dd if=/dev/zero of=filename bs=1 count=0 seek=200M

#gigabytes
dd if=/dev/zero of=filename bs=1 count=0 seek=200G

#terabytes
dd if=/dev/zero of=filename bs=1 count=0 seek=200T


Dalla manpage dd:

BLOCCHI e BYTES possono essere seguiti dai seguenti suffissi moltiplicativi: c = 1, w = 2, b = 512, kB = 1000, K = 1024, MB = 1000 * 1000, M = 1024 * 1024, GB = 1000 * 1000 * 1000, G = 1024 * 1024 * 1024 e così via per T, P, E, Z, Y.


Sembra molto meglio del modo n-1 , quindi è sostanzialmente equivalente a truncate.
Pavel Šimerda,

19

Per creare un file da 1 GB:

dd if=/dev/zero of=filename bs=1G count=1

7
Credo che il conteggio debba essere 1. (testato su centos)
SvennD

dd if=/dev/zero of=filename bs=20G count=1creerà solo file da 2 GB! non 20 GB.
Maulik Gangani,

18

Non so molto su Linux, ma ecco il codice C che ho scritto per falsificare file enormi su DC Share molti anni fa.

#include < stdio.h >
#include < stdlib.h >

int main() {
    int i;
    FILE *fp;

    fp=fopen("bigfakefile.txt","w");

    for(i=0;i<(1024*1024);i++) {
        fseek(fp,(1024*1024),SEEK_CUR);
        fprintf(fp,"C");
    }
}

ci devono essere approcci migliori in C. È inoltre necessario chiudere il file. Passando a un milione di persone scrivendo 1 carattere alla volta ...
ACV

10

Puoi anche usare il comando "si". La sintassi è abbastanza semplice:

#yes >> myfile

Premi "Ctrl + C" per fermarlo, altrimenti consumerà tutto il tuo spazio disponibile.

Per pulire questo file eseguito:

#>myfile

pulirà questo file.


7

Non penso che diventerai molto più veloce di dd. Il collo di bottiglia è il disco; scrivere centinaia di GB di dati richiederà molto tempo, indipendentemente da come lo si fa.

Ma ecco una possibilità che potrebbe funzionare per la tua applicazione. Se non ti interessa il contenuto del file, che ne dici di creare un file "virtuale" il cui contenuto sia l'output dinamico di un programma? Invece di aprire () il file, usa popen () per aprire una pipe verso un programma esterno. Il programma esterno genera dati ogni volta che è necessario. Una volta che la pipe è aperta, si comporta come un normale file in quanto il programma che ha aperto la pipe può fseek (), rewind (), ecc. Dovrai usare pclose () invece di close () quando sei fatto con il tubo.

Se la tua applicazione ha bisogno che il file abbia una certa dimensione, spetterà al programma esterno tenere traccia di dove si trova il "file" e inviare un eof quando è stata raggiunta la "fine".


4

Un approccio: se è possibile garantire che le applicazioni non correlate non utilizzino i file in modo contrastante, è sufficiente creare un pool di file di dimensioni diverse in una directory specifica, quindi creare collegamenti ad essi quando necessario.

Ad esempio, disporre di un pool di file chiamato:

  • / Home / bigfiles / 512M-A
  • / Home / bigfiles / 512M-B
  • / Home / bigfiles / 1024M-A
  • / Home / bigfiles / 1024M-B

Quindi, se hai un'applicazione che richiede un file 1G chiamato / home / oracle / logfile, esegui un "ln /home/bigfiles/1024M-A /home/oracle/logfile ".

Se è su un filesystem separato, dovrai usare un link simbolico.

I file A / B / etc possono essere utilizzati per garantire che non vi siano conflitti di utilizzo tra applicazioni non correlate.

L'operazione di collegamento è più veloce che puoi ottenere.


Puoi avere una piccola piscina o una grande piscina, è la tua scelta. Avresti avuto comunque bisogno di almeno un file, poiché è quello che ha chiesto l'interrogante. Se il tuo pool è costituito da un file, non perdi nulla. Se hai bucketload di disco (e dovresti, dato il suo prezzo basso), non c'è problema.
paxdiablo,

3

Il mkfile GPL è solo un (ba) sh wrapper di script attorno a dd; Il mkfile di BSD memorizza un buffer con un valore diverso da zero e lo scrive ripetutamente. Non mi aspetterei che il primo superasse il dd. Quest'ultimo potrebbe superare leggermente dd if = / dev / zero poiché omette le letture, ma tutto ciò che fa significativamente meglio probabilmente sta semplicemente creando un file sparse.

In assenza di una chiamata di sistema che alloca effettivamente lo spazio per un file senza scrivere dati (e Linux e BSD mancano di questo, probabilmente anche Solaris) potresti ottenere un piccolo miglioramento delle prestazioni usando ftrunc (2) / truncate (1) per estendere il file alla dimensione desiderata, mmap il file in memoria, quindi scrivere dati diversi da zero nei primi byte di ogni blocco del disco (utilizzare fgetconf per trovare la dimensione del blocco del disco).


4
BSD e Linux hanno effettivamente fallocate (modifica: ora è POSIX e ampiamente disponibile).
Tobu,

3

Spina senza vergogna: OTFFS fornisce un file system che fornisce file arbitrariamente grandi (beh, quasi. Exabyte è il limite attuale) di contenuto generato. È solo per Linux, semplice C e nei primi anni alfa.

Vedi https://github.com/s5k6/otffs .


3

Questo è il più veloce che potessi fare (che non è veloce) con i seguenti vincoli:

  • L'obiettivo del file di grandi dimensioni è quello di riempire un disco, quindi non può essere comprimibile.
  • Utilizzo del filesystem ext3. ( fallocatenon disponibile)

Questo è il senso di ciò ...

// include stdlib.h, stdio.h, and stdint.h
int32_t buf[256]; // Block size.
for (int i = 0; i < 256; ++i)
{
    buf[i] = rand(); // random to be non-compressible.
}
FILE* file = fopen("/file/on/your/system", "wb");
int blocksToWrite = 1024 * 1024; // 1 GB
for (int i = 0; i < blocksToWrite; ++i)
{
   fwrite(buf, sizeof(int32_t), 256, file);
}

Nel nostro caso questo è per un sistema Linux incorporato e funziona abbastanza bene, ma preferirebbe qualcosa di più veloce.

Cordiali saluti il ​​comando è dd if=/dev/urandom of=outputfile bs=1024 count = XXstato così lento da essere inutilizzabile.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.