Linuxシステムで大きなファイルをすばやく作成する


438

Linux(Red Hat Linux)システムで大きなファイルをすばやく作成するにどうすればよいですか?

ddは問題なく動作/dev/zeroしますが、テストのために数百GBのサイズのファイルが必要な場合は、ドライブからの読み取りとドライブへの書き込みに長い時間がかかる可能性があります。

ファイルの内容は気にせず、すばやく作成したいだけです。これはどのように行うことができますか?

スパースファイルの使用は、これでは機能しません。ファイルにディスク領域を割り当てる必要があります。


1
最大100MBのブロック全体を一度に割り当てることができるため、Ext4のファイル割り当てパフォーマンスははるかに優れています。
マルティヌス

5
ところで、 'truncate'コマンドはスパースファイルを作成します。たとえば、en.wikipedia.org / wiki / Sparse_fileを
Jason Drew

2
人々は、「スパースファイルはこれでは機能しない」ことを大きく無視しているようで、以下に切り捨てとddシークがあります。
hpavc 2016

1
「テスト用」で何を意味するかを定義しておく必要があります。ハードディスクの書き込み速度をテストしていますか?何dfを報告するかをテストしますか?特定のことを行うアプリをテストする。答えは、テストする対象によって異なります。とにかく私は少し遅れています
わかり

1
フルパーティションをシミュレートする方法を探している場合に備えて、私がそうであったように、/ dev / full
Julian

回答:


509

dd他の回答からの回答は良い解決策ですが、この目的には時間がかかります。Linux(およびその他のPOSIXシステム)では、fallocate実際に書き込むことなく目的のスペースを使用し、最新のディスクベースのファイルシステムで非常に高速に動作します。

例えば:

fallocate -l 10G gentoo_root.img

5
ddが既に内部的に使用している可能性はありますか?3.0.0カーネルで「dd if = / dev / zero of = zerofile bs = 1G count = 1」を実行すると、書き込みは2秒で終了し、書き込みデータレートは500メガバイト/秒を超えます。これは、2.5"ラップトップのハードドライブ上明確に不可能です。
lxgr

21
fallocateまさに私が探していたものです。
AB

7
これ(fallocate)はLinux ZFSファイルシステムでも機能しません-github.com/zfsonlinux/zfs/issues/326
Joe

5
fallocateもext3ではサポートされていません。 bugzilla.redhat.com/show_bug.cgi?id=563492
Eddie

3
Debianでは、GNU / Linux fallocateutil-linuxパッケージの一部です。このツールはRedHatのKarel Zakによって作成され、ソースコードは次の場所にあります:kernel.org/pub/linux/utils/util-linux
Franta

295

これはよくある質問です。特に、今日の仮想環境ではそうです。残念ながら、その答えは想定されるほど簡単ではありません。

ddは明白な最初の選択肢ですが、ddは基本的にコピーであり、データのすべてのブロックを書き込むことを強制します(したがって、ファイルの内容を初期化します)...そして、その初期化は非常に多くのI / O時間を要します。(さらに時間がかかりますか?/ dev / zeroの代わりに/ dev / randomを使用してください!次に、CPUとI / O時間を使用します!)ただし、最終的には、ddは不適切な選択です(ただし、 VMの「作成」GUIで使用されるデフォルト)。例えば:

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

切り捨ては別の選択肢です-おそらく最速です...しかし、それは「スパースファイル」を作成するためです。基本的に、スパースファイルは、同じデータがたくさんあるディスクのセクションであり、基礎となるファイルシステムは、実際にはすべてのデータを格納するのではなく、すべてが存在することを "偽装"することで「だまされます」。したがって、truncateを使用してVMに20 GBのドライブを作成すると、ファイルシステムは実際には20 GBを割り当てませんが、ディスク上のトラックが1つしかない場合でも、チートしてゼロが20 GBあると表示されます実際に(実際に)使用されている可能性があります。例えば:

 truncate -s 10G gentoo_root.img

fallocateは、 VMディスク割り当てで使用するため最後の(そして最良の選択です。なぜなら、それは本質的に、探しているすべての領域を「予約」(または「割り当て」)ますが、何も書く必要がないからです。 fallocateを使用して20 GBの仮想ドライブスペースを作成すると、実際には20 GBのファイル(「スパースファイル」ではない)が得られ、何も書き込む必要はありません。つまり、実質的に何でもあります-まるで新しいディスクのようなものです!)例:

fallocate -l 10G gentoo_root.img

4
+1 truncateはJFSで機能します。fallocate、それほどではありません。1つのポイント:数値に小数を含めることはできませ1536G1.5T。指定する必要がありました。
Calrion 2014

1
私によると、fallocatemanページ、これはのみでサポートされていますbtrfsext4ocfs2、およびxfsファイルシステム
ネイサンS.ワトソン・ヘーグ

swapon残念ながら事前に割り当てられたエクステントの作品にはない、最後に私がチェックしました。XFSメーリングリストで、代わりに古い空き領域データを公開し、エクステントが事前割り当て済みとしてマークされていないため、swaponが機能することについて、いくつかの議論がありました。しかし、私は何も行われなかったと思います。
Peter Cordes

1
参考までに、あまりにも多くのデータを読み取ろうとすると/dev/random、ランダムデータが不足する可能性があります。「エントロピープールが空の場合、/ dev / randomからの読み取りは、追加の環境ノイズが収集されるまでブロックされます」ので、非常に非常に時間がかかる可能性があります。長い時間
Xen2050、2017年

154

Linuxおよびすべてのファイルシステム

xfs_mkfile 10240m 10Gigfile

Linuxおよび一部のファイルシステム(ext4、xfs、btrfs、ocfs2)

fallocate -l 10G 10Gigfile

OS X、Solaris、SunOS、そしておそらく他のUNIX

mkfile 10240m 10Gigfile

HP-UX

prealloc 10Gigfile 10737418240

説明

mkfile <size>代わりにmyfileを試してくださいdd。では-nオプションサイズが注目されるが、データが書き込まれるまでディスクブロックが割り当てられていません。-nオプションがない場合、スペースはゼロで埋められます。つまり、ディスクへの書き込み、つまり時間がかかります。

mkfileはSunOSから派生したもので、どこでも利用できるわけではありません。ほとんどのLinuxシステムはxfs_mkfile、名前にかかわらず、XFSファイルシステムだけでなく、まったく同じように機能します。xfsprogs(Debian / Ubuntu用)または同様の名前付きパッケージに含まれています。

ほとんどのLinuxシステムにもがありfallocate、特定のファイルシステム(btrfs、ext4、ocfs2、xfsなど)でのみ機能しますが、すべてのファイルスペースを割り当て(非ホールファイルを作成)、初期化しないため、最速です。それの。


5
あなたが話すこのmkfileはどこですか、見知らぬ人ですか?デフォルトのRHELインストールには含まれていません。
paxdiablo 2008年

2
それはソラリスユーティリティです。gpl mkfileを検索すると、いくつかのソースコードの例が見つかります。
Martin Beckett、

5
OS Xでチャームとして機能します:mkfile 1g DELETE_IF_LOW_ON_SSD_SPACE.img
Volker Rose

2
xfs_mkfileUbuntuのxfsprogsに含まれていて、私のext3 fsのチャームのように動作します。:)
Greg Dubicki、2015

97
truncate -s 10M output.file

10 Mファイルを瞬時に作成します(Mは1024 * 1024バイトを表し、MBは1000 * 1000を表します-K、KB、G、GBと同じ...)

編集:多くの人が指摘しているように、これはデバイスにファイルを物理的に割り当てることはしません。これにより、「スパース」ファイルが作成されるため、デバイス上の使用可能なスペースに関係なく、任意の大きなファイルを実際に作成できます。

そのため、これを行うと、ファイルがアクセスされるまで物理割り当てが延期されます。このファイルをメモリにマッピングしている場合、期待したパフォーマンスが得られない可能性があります。

しかし、これはまだ知っておくと便利なコマンドです


1
これを試しましたが、使用可能なディスク容量には影響しません。前述のようにスパースファイルであるためです。
Gringo Suave

7
これは問題を解決しないので、これが一番の答えになるべきではありませんfallocate。以下の答えはそうです。
Gringo Suave

4
@GringoSuaveですが、これは、類似しているが少し異なる問題を抱えている可能性がある一部の人々にとっては依然として役立ちます。
AJMansfield 2013年

@GringoSuave:要求通りに大きなファイルを作成するようですが、なぜ問題が解決しないのですか?また、fallocateの回答の下には、ほとんどの場合に機能しないというメモがあります。
PavelŠimerda2014

1
彼がうまくいかないと彼が言ったとき、なぜスパースファイルを作ることを勧めますか?
hpavc 2016

44

ここで、シークはバイト単位での必要なファイルのサイズです-1。

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

6
私はこのアプローチが好きですが、コメンターは何らかの理由でスパースファイルを望んでいません。:(
ephemient 2008年

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
スパースファイルの場合truncateは、はるかに良いようです。
PavelŠimerda2014

36

seekが必要なファイルのサイズ(バイト単位)である例

#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


ddマンページから:

BLOCKSおよびBYTESの後には、次の乗法サフィックスが続く場合があります:c = 1、w = 2、b = 512、kB = 1000、K = 1024、MB = 1000 * 1000、M = 1024 * 1024、GB = 1000 * 1000 * 1000、G = 1024 * 1024 * 1024など、T、P、E、Z、Yの場合。


これはn-1の方法よりはるかに良く見えるので、基本的にはと同等truncateです。
PavelŠimerda2014

19

1 GBファイルを作成するには:

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

7
カウントは1である必要があると思います(centosでテスト済み)
SvennD 2015年

dd if=/dev/zero of=filename bs=20G count=12GBファイルのみを作成します!20GBではありません。
Maulik Gangani 2017

18

Linuxについてはよく知りませんが、何年も前にDC Shareで巨大なファイルを偽造するために書いたCコードを以下に示します。

#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");
    }
}

Cにはより優れたアプローチが必要です。ファイルを閉じる必要もあります。一度に1文字を書き込む100万まで反復する...
ACV

10

「yes」コマンドも使用できます。構文はかなり単純です:

#yes >> myfile

これを停止するには「Ctrl + C」を押します。それ以外の場合は、使用可能なスペースがすべて消費されます。

このファイルを消去するには、次を実行します。

#>myfile

このファイルを消去します。


7

私はあなたがddよりもずっと速くなるとは思わない。ボトルネックはディスクです。数百GBのデータをそこに書き込むには、どのように実行しても長い時間がかかります。

しかし、これがアプリケーションで機能する可能性があります。ファイルの内容が気にならない場合は、プログラムの動的出力を内容とする「仮想」ファイルを作成してみませんか。ファイルをopen()する代わりに、popen()を使用して外部プログラムへのパイプを開きます。外部プログラムは、必要なときにいつでもデータを生成します。パイプが開くと、パイプを開いたプログラムがfseek()、rewind()などを実行できるという点で、通常のファイルと同じように機能します。パイプで終わりました。

アプリケーションが特定のサイズのファイルを必要とする場合、「プログラム」のどこにあるかを追跡し、「終了」に達したときにeofを送信するのは外部プログラム次第です。


4

1つのアプローチ:関連のないアプリケーションが競合する方法でファイルを使用しないことが保証できる場合は、特定のディレクトリにさまざまなサイズのファイルのプールを作成し、必要に応じてそれらへのリンクを作成します。

たとえば、次のようなファイルのプールがあるとします。

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

次に、/ home / oracle / logfileという1Gファイルを必要とするアプリケーションがある場合は、「ln /home/bigfiles/1024M-A /home/oracle/logfile」を実行します。

別のファイルシステムにある場合は、シンボリックリンクを使用する必要があります。

A / B / etcファイルを使用して、関連のないアプリケーション間で使用が競合しないようにすることができます。

リンク操作は、可能な限り高速です。


あなたは小さなプールまたは大きなプールを持つことができます、それはあなたの選択です。とにかく少なくとも1つのファイルが必要になります。質問者がそれを求めたからです。プールが1つのファイルで構成されている場合、何も失うことはありません。あなたがディスクのバケットロードを持っているなら(そしてあなたは、その低価格を考えると、そうすべきです)、問題はありません。
paxdiablo 2008年

3

GPL mkfileはddの(ba)shスクリプトラッパーにすぎません。BSDのmkfileは、ゼロ以外のバッファをmemsetsし、それを繰り返し書き込みます。前者がddを上回るとは思いません。後者は読み取りを省略しているため、dd if = / dev / zeroをわずかに除外する可能性がありますが、大幅に向上するものは、おそらくスパースファイルを作成することだけです。

データを書き込まずに実際にファイルにスペースを割り当てるシステムコールがない場合(およびLinuxとBSDにはこれがあり、おそらくSolarisも同様です)、ファイルを拡張するためにftrunc(2)/ truncate(1)を使用すると、パフォーマンスが少し向上する可能性があります目的のサイズにするには、ファイルをメモリにmmapしてから、すべてのディスクブロックの最初のバイトにゼロ以外のデータを書き込みます(fgetconfを使用してディスクブロックサイズを見つけます)。


4
BSDとLinuxは実際に大混乱しています(編集:現在POSIXであり、広く利用可能です)。
東武

3

恥知らずなプラグイン:OTFFSは、生成されたコンテンツの任意に大きな(まあ、ほぼエクサバイトが現在の制限です)ファイルを提供するファイルシステムを提供します。これはLinux専用のプレーンCで、初期のアルファ版です。

https://github.com/s5k6/otffsを参照してください


3

これは、次の制約で私ができる最速です(これは高速ではありません)。

  • 大きなファイルの目的はディスクをいっぱいにすることなので、圧縮できません。
  • ext3ファイルシステムを使用します。(fallocate利用できません)

これがその要点です...

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

私たちの場合、これは組み込みLinuxシステム用であり、これは十分に機能しますが、より高速なものを好みます。

参考までに、コマンドdd if=/dev/urandom of=outputfile bs=1024 count = XXは非常に遅いため使用できませんでした。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.