どうすれば素早くLinux( Red Hat Linux )システムに大きなファイルを作成できますか?
dd が動作しますが、数百GBのファイルが必要な場合は、/dev/zero
からの読み込みとドライブへの書き込みに長い時間がかかることがあります。テストしています...これを繰り返し行う必要がある場合は、実際に時間がかかります。
ファイルの内容は気にしないで、すばやく作成したいだけです。どうすればこれができますか?
スパースファイルを使用してもこれには効果がありません。ファイルにディスクスペースを割り当てる必要があります。
他の答えからのdd
は良い解決策ですが、この目的のために遅いです。 Linux(および他のPOSIXシステム)には、実際に書き込む必要なしに目的のスペースを使用するfallocate
があります。これは、ほとんどの最新のディスクベースのファイルシステムで非常に高速に動作します。
例えば:
fallocate -l 10G gentoo_root.img
これはよくある質問です - 特に今日の仮想環境の環境では。残念ながら、答えは想像できるほど簡単ではありません。
ddは明らかに最初の選択ですが、ddは本質的にコピーであり、データのすべてのブロックを書き込むように強制します(したがって、ファイルの内容を初期化する)...そして、その初期化はI/O時間を非常にかかります。 (さらに時間をかけたい場合は、 / dev/zero の代わりに / dev/random を使用してください。 I/O時間!)しかし、結局のところ、ddは不適切な選択です(ただし、VM "create" GUIで使用されるデフォルトの設定が基本です)。例えば:
dd if=/dev/zero of=./gentoo_root.img bs=4k iflag=fullblock,count_bytes count=10G
truncate は別の選択です - そしておそらく最速です...しかし、それは "スパースファイル"を作成するためです。基本的に、スパースファイルとは同じデータを多く含むディスクの一部であり、基礎となるファイルシステムは実際にはすべてのデータを格納するのではなく、すべてがそこにあるというふりをすることで「不正」になります。したがって、VM用に20 GBのドライブを作成するためにtruncateを使用すると、ファイルシステムは実際には20 GBを割り当てませんが、ディスク上のトラックが1トラックであっても、そこには20 GBのゼロがあります。実際に(実際に)使用されている可能性があります。例えば。:
truncate -s 10G gentoo_root.img
fallocateは、最後の - および最良の - の選択で使用します。 VMディスク割り当て。基本的には探しているすべてのスペースを「予約」(または「割り当て」)しますが、何も書く必要はありません。 GBの仮想ドライブスペース、あなたは本当に20GBのファイル(「スパースファイル」ではない)を手に入れます、そしてそれに何かを書くことに煩わされることはありません - それは事実上何でもそこにあることを意味します新しいディスク!)例:
fallocate -l 10G gentoo_root.img
xfs_mkfile 10240m 10Gigfile
fallocate -l 10G 10Gigfile
mkfile 10240m 10Gigfile
prealloc 10Gigfile 10737418240
dd
の代わりにmkfile <size>
myfileを試してください。 -n
オプションを指定するとサイズが記録されますが、データが書き込まれるまでディスクブロックは割り当てられません。 -n
オプションを指定しないと、スペースはゼロで埋められます。つまり、ディスクへの書き込みは時間がかかります。
mkfile はSunOSから派生したもので、至るところで利用できるわけではありません。ほとんどのLinuxシステムは xfs_mkfile
を持っていますが、これは名前にかかわらずXFSファイルシステムだけではありません。 xfsprogs(Debian/Ubuntuの場合)またはそれに類似した名前のパッケージに含まれています。
ほとんどのLinuxシステムには fallocate
もあります。これは特定のファイルシステム(btrfs、ext4、ocfs2、xfsなど)でのみ動作しますが、最も高速です。すべてのファイルスペースを割り当てます(穴の開いていないファイルを作成します)が、初期化はしません。
truncate -s 10M output.file
即座に10 Mのファイルを作成します(Mは1024 * 1024バイト、MBは1000 * 1000を表します - K、KB、G、GBと同じ)。
編集:多くの人が指摘しているように、これは物理的にあなたのデバイスにファイルを割り当てることはありません。これを使用すると、「スパース」ファイルが作成されるため、デバイスの空き容量に関係なく、実際に任意の大きなファイルを作成できます。
したがって、これを行うと、ファイルがアクセスされるまで物理的な割り当てを延期することになります。このファイルをメモリにマップしている場合は、期待どおりのパフォーマンスが得られない可能性があります。
しかし、これはまだ知っておくと便利なコマンドです
Seekは、必要なファイルのサイズ(バイト単位)です。
dd if=/dev/zero of=filename bs=1 count=1 seek=1048575
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のマンページから:
ブロックおよびバイトの後には、次の乗法的接尾辞が続くことがあります。 T、P、E、Z、Yの場合、1000、G = 1024 * 1024 * 1024のようになります。
私はLinuxについてあまりよく知らないが、これは私が何年も前にDCShareに巨大なファイルを偽造するために書いた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");
}
}
1 GBのファイルを作るには:
dd if=/dev/zero of=filename bs=1G count=1
"yes"コマンドも使えます。構文はかなり単純です。
#yes >> myfile
これを止めるには "Ctrl + C"を押してください。さもなければそれは利用可能なあなたのスペース全てを使い果たします。
このファイルをきれいにするには:
#>myfile
このファイルをきれいにします。
私はあなたがDDよりはるかに速くなるつもりはないと思います。ボトルネックはディスクです。何百GBものデータを書き込むには、どのようにしても長い時間がかかります。
しかし、これはあなたのアプリケーションでうまくいく可能性があります。ファイルの内容を気にしないのであれば、内容がプログラムの動的出力である「仮想」ファイルを作成するのはどうでしょうか。ファイルを開く()代わりに、popen()を使用して外部プログラムへのパイプを開きます。外部プログラムは必要に応じてデータを生成します。パイプが開かれると、パイプを開いたプログラムがfseek()、rewind()などを実行できるという点で、通常のファイルとまったく同じように機能します。パイプでやった。
あなたのアプリケーションがファイルがあるサイズであることを必要とするならば、それが「ファイル」のどこにあるかを追跡して、「終わり」に達したときにeofを送ることは外部プログラム次第です。
1つのアプローチ:無関係なアプリケーションがファイルを矛盾した方法で使用しないことを保証できる場合は、特定のディレクトリにさまざまなサイズのファイルのプールを作成し、必要に応じてそれらへのリンクを作成します。
たとえば、次のようなファイルのプールがあります。
次に、/ home/Oracle/logfileという1Gファイルが必要なアプリケーションがある場合は、 "ln /home/bigfiles/1024M-A /home/Oracle/logfile
"を実行します。
別のファイルシステムにある場合は、シンボリックリンクを使用する必要があります。
A/B/etcファイルを使用して、関連のないアプリケーション間で競合する使用がないことを確認できます。
リンク操作はあなたが得ることができるのと同じくらい速いです。
恥知らずなプラグイン:OTFFSは、生成されたコンテンツの任意の大きさの(よく、Exabytesが現在の制限です)ファイルを提供するファイルシステムを提供します。これはLinuxのみで、プレーンCで、初期のアルファ版です。
https://github.com/s5k6/otffs を参照してください。
GPL mkfileは、ddを囲む単なる(ba)shスクリプトラッパーです。 BSDのmkfileはバッファを0以外でmemsetし、それを繰り返し書き込みます。私は前者がddを凌駕するとは思わないでしょう。後者は読み込みを省いているのでdd if =/dev/zeroを少し外に出すかもしれませんが、おそらくもっと良い方法はスパースファイルを作成することです。
データを書き込まずに実際にファイルのためのスペースを割り当てるシステムコールがないと(そしてLinuxとBSDはこれを欠いています。おそらくSolarisもそうです)、ファイルを拡張するためにftrunc(2)/ truncate(1)を使うことでパフォーマンスが少し向上するでしょう。目的のサイズにするには、ファイルをメモリにmmapしてから、すべてのディスクブロックの最初のバイトにゼロ以外のデータを書き込みます(ディスクブロックサイズを見つけるにはfgetconfを使用します)。
これは私ができる最速のものです(これは速くない)、次のような制約があります。
これがその要点です… `
// 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"は非常に遅くて使用できませんでした。