Erstellen Sie schnell eine große Datei auf einem Linux-System

437

Wie kann ich schnell eine große Datei auf einem Linux- System ( Red Hat Linux ) erstellen ?

dd/dev/zero erledigt den Job, aber das Lesen von und Schreiben auf das Laufwerk kann lange dauern, wenn Sie eine Datei mit einer Größe von mehreren hundert GB zum Testen benötigen ... Wenn Sie dies wiederholt tun müssen, summiert sich die Zeit wirklich.

Der Inhalt der Datei ist mir egal, ich möchte nur, dass sie schnell erstellt wird. Wie kann das gemacht werden?

Die Verwendung einer Sparse-Datei funktioniert hierfür nicht. Ich muss der Datei Speicherplatz zugewiesen bekommen.

DrStalker
quelle
1
Ext4 bietet eine viel bessere Dateizuordnungsleistung, da ganze Blöcke mit bis zu 100 MB gleichzeitig zugewiesen werden können.
Martinus
5
Der Befehl 'Abschneiden' erstellt übrigens eine Datei mit geringer Dichte. ZB siehe en.wikipedia.org/wiki/Sparse_file
Jason Drew
2
Die Leute scheinen die "spärliche Datei funktioniert damit nicht" grob zu ignorieren, mit ihren abgeschnittenen und dd-Suchanfragen unten.
HPVC
1
Sie sollten definiert haben, was Sie mit "zum Testen" gemeint haben. Testen Sie die Schreibgeschwindigkeit Ihrer Festplatte? Testen, was dfgemeldet wird? Testen einer App, die etwas Besonderes tut. Die Antwort hängt davon ab, was Sie testen möchten. Wie auch immer, ich bin ein bisschen spät
dran
1
Nur für den Fall, dass Sie nach einer Möglichkeit suchen, eine vollständige Partition zu simulieren, wie ich es war, suchen Sie nicht weiter als / dev / full
Julian

Antworten:

508

ddVon den anderen Antworten ist eine gute Lösung, aber es ist langsam für diesen Zweck. Unter Linux (und anderen POSIX-Systemen) funktioniert das System fallocate, das den gewünschten Speicherplatz nutzt, ohne darauf schreiben zu müssen, sehr schnell mit den meisten modernen festplattenbasierten Dateisystemen:

Zum Beispiel:

fallocate -l 10G gentoo_root.img
Franta
quelle
5
Ist es möglich, dass dd das bereits intern verwendet? Wenn ich auf einem 3.0.0-Kernel 'dd if = / dev / zero of = zerofile bs = 1G count = 1' mache, endet der Schreibvorgang in 2 Sekunden mit einer Schreibdatenrate von über 500 Megabyte pro Sekunde. Das ist auf einer 2,5-Zoll-Laptop-Festplatte eindeutig unmöglich.
lxgr
21
fallocateist genau das, wonach ich gesucht habe.
AB
7
Dies ( fallocate) funktioniert auch nicht auf einem Linux ZFS-Dateisystem - github.com/zfsonlinux/zfs/issues/326
Joe
5
fallocate wird auch von ext3 nicht unterstützt. bugzilla.redhat.com/show_bug.cgi?id=563492
Eddie
3
In Debian ist GNU / Linux fallocateTeil des util-linuxPakets. Dieses Tool wurde von Karel Zak von RedHat geschrieben und der Quellcode ist hier zu finden: kernel.org/pub/linux/utils/util-linux
Franta
294

Dies ist eine häufige Frage - insbesondere in der heutigen Umgebung virtueller Umgebungen. Leider ist die Antwort nicht so einfach, wie man annehmen könnte.

dd ist die offensichtliche erste Wahl, aber dd ist im Wesentlichen eine Kopie, die Sie dazu zwingt, jeden Datenblock zu schreiben (wodurch der Dateiinhalt initialisiert wird) ... Und diese Initialisierung nimmt so viel E / A-Zeit in Anspruch. (Möchten Sie, dass es noch länger dauert ? Verwenden Sie / dev / random anstelle von / dev / zero ! Dann verwenden Sie sowohl die CPU- als auch die E / A-Zeit!) Am Ende ist dd jedoch eine schlechte Wahl (obwohl im Wesentlichen die Standardmäßig wird von der VM "GUIs erstellen" verwendet. Z.B:

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

Abschneiden ist eine andere Wahl - und wahrscheinlich die schnellste ... Aber das liegt daran, dass eine "spärliche Datei" erstellt wird. Im Wesentlichen ist eine Datei mit geringer Dichte ein Abschnitt der Festplatte, der viele der gleichen Daten enthält, und das zugrunde liegende Dateisystem "betrügt", indem es nicht wirklich alle Daten speichert, sondern nur "vorgibt", dass alles vorhanden ist. Wenn Sie also Truncate verwenden, um ein 20-GB-Laufwerk für Ihre VM zu erstellen, weist das Dateisystem tatsächlich keine 20 GB zu, aber es betrügt und sagt, dass dort 20 GB Nullen vorhanden sind, obwohl nur eine Spur auf der Festplatte vorhanden ist kann tatsächlich (wirklich) in Gebrauch sein. Z.B:

 truncate -s 10G gentoo_root.img

fallocate ist die letzte - und besten - Wahl für die Verwendung mit der Datenträgerzuweisung VM, da es im Wesentlichen „Reserven“ (oder „zuordnet“ alle des Raumes Sie suchen, aber es nicht zu schreiben etwas stört also. Wenn Sie mit fallocate einen virtuellen Speicherplatz von 20 GB erstellen, erhalten Sie tatsächlich eine 20-GB-Datei (keine "spärliche Datei"), und Sie haben sich nicht die Mühe gemacht, etwas darauf zu schreiben - was bedeutet, dass praktisch alles darin sein könnte da - irgendwie wie eine brandneue Scheibe!) ZB:

fallocate -l 10G gentoo_root.img
Dan McAllister
quelle
4
+1 truncateist in JFS funktionsfähig; fallocate, nicht so viel. Ein Punkt: Sie können keine Dezimalstelle in die Zahl aufnehmen, die ich angeben musste 1536G, nicht 1.5T.
Calrion
1
Nach meinen fallocateMann Seite ist dies nur auf unterstützten btrfs, ext4, ocfs2, und xfsDateisysteme
Nathan S. Watson-Haigh
Hinweis swaponfunktioniert leider nicht bei vorab zugewiesenen Extents, die ich zuletzt überprüft habe. Auf der XFS-Mailingliste gab es einige Diskussionen darüber, dass stattdessen eine Fallocate-Option zum Offenlegen der alten Freespace-Daten und nicht als vorab zugewiesene Ausdehnung verfügbar sein sollte, damit Swapon funktioniert. Aber ich glaube nicht, dass jemals etwas getan wurde.
Peter Cordes
1
Zu Ihrer Information: Der Versuch, zu viele Daten zu lesen, /dev/randomkann dazu führen , dass keine zufälligen Daten mehr vorhanden sind. "Wenn der Entropiepool leer ist, werden Lesevorgänge aus / dev / random blockiert, bis zusätzliche Umgebungsgeräusche erfasst werden", sodass dies sehr, sehr, sehr lange dauern kann lange Zeit
Xen2050
154

Linux & alle Dateisysteme

xfs_mkfile 10240m 10Gigfile

Linux & und einige Dateisysteme (ext4, xfs, btrfs und ocfs2)

fallocate -l 10G 10Gigfile

OS X, Solaris, SunOS und wahrscheinlich andere UNIX

mkfile 10240m 10Gigfile

HP-UX

prealloc 10Gigfile 10737418240

Erläuterung

Versuchen Sie mkfile <size>myfile als Alternative zu dd. Mit der -nOption wird die Größe notiert, aber Plattenblöcke werden erst zugewiesen, wenn Daten in sie geschrieben wurden. Ohne die -nOption ist der Speicherplatz mit Nullen gefüllt, was bedeutet, dass auf die Festplatte geschrieben wird, was bedeutet, dass Sie sich Zeit nehmen müssen.

mkfile ist von SunOS abgeleitet und nicht überall verfügbar. Die meisten Linux-Systeme xfs_mkfilefunktionieren genauso und nicht nur auf XFS-Dateisystemen trotz des Namens. Es ist in xfsprogs (für Debian / Ubuntu) oder ähnlichen Paketen enthalten.

Die meisten Linux-Systeme haben auch fallocate, was nur auf bestimmten Dateisystemen (wie btrfs, ext4, ocfs2 und xfs) funktioniert, aber am schnellsten ist, da es den gesamten Dateibereich zuweist (erstellt nicht-löchrige Dateien), aber keine initialisiert davon.

CMS
quelle
5
Wo ist diese Datei, von der du sprichst, Fremder? Es ist nicht in der Standard-RHEL-Installation.
Paxdiablo
2
Es ist ein Solaris-Dienstprogramm. Wenn Sie nach gpl mkfile suchen, finden Sie einige Beispiele für Quellcode.
Martin Beckett
5
Funktioniert als Charme unter OS X:mkfile 1g DELETE_IF_LOW_ON_SSD_SPACE.img
Volker Rose
2
xfs_mkfileist in xfsprogs unter Ubuntu enthalten und funktioniert wie ein Zauber auf meinem ext3 fs. :)
Greg Dubicki
97
truncate -s 10M output.file

erstellt sofort eine 10-M-Datei (M steht für 1024 * 1024 Bytes, MB steht für 1000 * 1000 - wie bei K, KB, G, GB ...)

BEARBEITEN: Wie viele darauf hingewiesen haben, wird die Datei auf Ihrem Gerät dadurch nicht physisch zugeordnet. Mit dieser Funktion können Sie unabhängig vom verfügbaren Speicherplatz auf dem Gerät eine beliebig große Datei erstellen, da eine "spärliche" Datei erstellt wird.

Wenn Sie dies tun, verschieben Sie die physische Zuordnung, bis auf die Datei zugegriffen wird. Wenn Sie diese Datei dem Speicher zuordnen, haben Sie möglicherweise nicht die erwartete Leistung.

Dies ist jedoch immer noch ein nützlicher Befehl

kiv
quelle
1
Versuchte dies, aber es hat keinen Einfluss auf den verfügbaren Speicherplatz. Muss, weil es eine spärliche Datei ist, wie zuvor beschrieben.
Gringo Suave
7
Dies sollte nicht die beste Antwort sein, da dies das Problem nicht löst. Die folgende fallocateAntwort tut dies.
Gringo Suave
4
@GringoSuave, aber dies ist immer noch nützlich für einige Leute, die möglicherweise ein ähnliches, aber etwas anderes Problem haben.
AJMansfield
@GringoSuave: Es scheint eine große Datei wie gewünscht zu erstellen, warum löst es das Problem nicht? Es gibt auch Hinweise unter der Fallocate-Antwort, dass es in den meisten Fällen nicht einmal funktioniert.
Pavel Šimerda
1
Warum vorschlagen, spärliche Dateien zu erstellen, wenn er sagte, dass dies nicht funktionieren wird?
HPVC
44

Wobei seek die Größe der gewünschten Datei in Bytes ist - 1.

dd if=/dev/zero of=filename bs=1 count=1 seek=1048575
Zoredache
quelle
6
Ich mag diesen Ansatz, aber der Kommentator möchte aus irgendeinem Grund keine spärliche Datei. :(
Ephemient
3
dd if = / dev / zero von = 1GBfile bs = 1000 count = 1000000
Damien
7
dd if = / dev / zero von = 01GBfile bs = 1024 count = $ ((1024 * 1024))
Xavier Decoret
1
Für spärliche Dateien truncatescheint es viel besser zu sein.
Pavel Šimerda
36

Beispiele, bei denen seek die Größe der gewünschten Datei in Byte ist

#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


Aus der dd-Manpage:

Auf BLÖCKE und BYTES können die folgenden multiplikativen Suffixe folgen: c = 1, w = 2, b = 512, kB = 1000, K = 1024, MB = 1000 * 1000, M = 1024 * 1024, GB = 1000 * 1000 * 1000, G = 1024 · 1024 · 1024 usw. für T, P, E, Z, Y.

Sepero
quelle
Dies sieht viel besser aus als der n-1- Weg, also ist es im Grunde gleichbedeutend mit truncate.
Pavel Šimerda
18

Ich weiß nicht viel über Linux, aber hier ist der C-Code, den ich geschrieben habe, um vor vielen Jahren riesige Dateien auf DC Share zu fälschen.

#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");
    }
}
Humungous Hippo
quelle
Es muss bessere Ansätze in C geben. Sie müssen auch die Datei schließen. Iterieren zu einer Million, die jeweils 1 Zeichen schreibt ...
ACV
18

So erstellen Sie eine 1-GB-Datei:

dd if=/dev/zero of=filename bs=1G count=1
max
quelle
7
Ich glaube, die Anzahl muss 1 sein. (Auf Centos getestet)
SvennD
dd if=/dev/zero of=filename bs=20G count=1erstellt nur 2GB Datei! nicht 20GB.
Maulik Gangani
9

Sie können auch den Befehl "Ja" verwenden. Die Syntax ist ziemlich einfach:

#yes >> myfile

Drücken Sie "Strg + C", um dies zu stoppen. Andernfalls wird der gesamte verfügbare Speicherplatz aufgebraucht.

So bereinigen Sie diese Datei:

#>myfile

wird diese Datei bereinigen.

Yogi
quelle
6

Ich glaube nicht, dass du viel schneller als dd wirst. Der Engpass ist die Festplatte; Das Schreiben von Hunderten von GB Daten wird lange dauern, egal wie Sie es tun.

Aber hier ist eine Möglichkeit, die für Ihre Anwendung funktionieren könnte. Wenn Sie sich nicht für den Inhalt der Datei interessieren, wie wäre es dann mit dem Erstellen einer "virtuellen" Datei, deren Inhalt die dynamische Ausgabe eines Programms ist? Verwenden Sie popen (), um eine Pipe zu einem externen Programm zu öffnen, anstatt die Datei zu öffnen (). Das externe Programm generiert Daten, wann immer sie benötigt werden. Sobald die Pipe geöffnet ist, verhält sie sich wie eine normale Datei, da das Programm, das die Pipe geöffnet hat, fseek (), rewind () usw. ausführen kann. Sie müssen pclose () anstelle von close () verwenden, wenn Sie sind fertig mit dem Rohr.

Wenn Ihre Anwendung eine bestimmte Größe der Datei benötigt, muss das externe Programm verfolgen, wo sich die Datei in der "Datei" befindet, und eine E-Mail senden, wenn das "Ende" erreicht ist.

Barry Brown
quelle
4

Ein Ansatz: Wenn Sie sicherstellen können, dass nicht verwandte Anwendungen die Dateien nicht in widersprüchlicher Weise verwenden, erstellen Sie einfach einen Pool von Dateien unterschiedlicher Größe in einem bestimmten Verzeichnis und erstellen Sie bei Bedarf Links zu diesen.

Haben Sie beispielsweise einen Dateipool mit dem Namen:

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

Wenn Sie eine Anwendung haben, die eine 1G-Datei mit dem Namen / home / oracle / logfile benötigt, führen Sie ein " ln /home/bigfiles/1024M-A /home/oracle/logfile" aus.

Wenn es sich in einem separaten Dateisystem befindet, müssen Sie einen symbolischen Link verwenden.

Die A / B / etc-Dateien können verwendet werden, um sicherzustellen, dass keine Konflikte zwischen nicht verwandten Anwendungen bestehen.

Der Link-Vorgang ist so schnell wie möglich.

paxdiablo
quelle
Sie können einen kleinen Pool oder einen großen Pool haben, Sie haben die Wahl. Sie würden sowieso mindestens eine Datei benötigen, da der Fragesteller darum gebeten hat. Wenn Ihr Pool aus einer Datei besteht, verlieren Sie nichts. Wenn Sie eine Menge Festplatten haben (und dies angesichts des niedrigen Preises tun sollten), gibt es kein Problem.
Paxdiablo
3

Die GPL-mk-Datei ist nur ein (ba) sh-Skript-Wrapper um dd; Die mk-Datei von BSD speichert nur einen Puffer mit einem Wert ungleich Null und schreibt ihn wiederholt. Ich würde nicht erwarten, dass der erstere dd übertrifft. Letzteres könnte dd if = / dev / zero leicht aus dem Weg räumen, da die Lesevorgänge weggelassen werden, aber alles, was wesentlich besser funktioniert, ist wahrscheinlich nur das Erstellen einer Datei mit geringer Dichte.

Ohne einen Systemaufruf, der tatsächlich Speicherplatz für eine Datei zuweist, ohne Daten zu schreiben (und Linux und BSD fehlt dies, wahrscheinlich auch Solaris), können Sie die Leistung geringfügig verbessern, indem Sie die Datei mit ftrunc (2) / truncate (1) erweitern Stellen Sie die Datei auf die gewünschte Größe in den Speicher ein und schreiben Sie dann Daten ungleich Null in die ersten Bytes jedes Plattenblocks (verwenden Sie fgetconf, um die Plattenblockgröße zu ermitteln).

Alex Dupuy
quelle
4
BSD und Linux haben tatsächlich Fallocate (bearbeiten: es ist jetzt POSIX und weit verbreitet).
Tobu
3

Schamloser Plug: OTFFS bietet ein Dateisystem, das beliebig große (nun ja, fast Exabyte ist das aktuelle Limit) Dateien mit generiertem Inhalt bereitstellt. Es ist nur Linux, einfaches C und in frühem Alpha.

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

stefan
quelle
3

Dies ist die schnellste (die nicht schnell ist) mit den folgenden Einschränkungen:

  • Das Ziel der großen Datei ist es, eine Festplatte zu füllen, sodass sie nicht komprimierbar ist.
  • Ext3-Dateisystem verwenden. ( fallocatenicht verfügbar)

Das ist der Kern davon ...

// 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);
}

In unserem Fall ist dies für ein eingebettetes Linux-System und dies funktioniert gut genug, würde aber etwas schnelleres bevorzugen.

Zu Ihrer Information, der Befehl dd if=/dev/urandom of=outputfile bs=1024 count = XXwar so langsam, dass er unbrauchbar wurde.

user79878
quelle