Linux上で,巨大なサイズのダミーファイルを作成する方法
Linux上で,巨大なサイズのダミーファイルが欲しい場合がある。
例えば,圧縮ソフトの圧縮率を比較したい場合など。
この場合,ダミーファイルの性質として,下記の点が求められる。
- 内容が,極端に「均質」過ぎてはいけない。(圧縮結果が小さくなりすぎるから)
- 内容が,極端に「ランダム」過ぎてはいけない。(圧縮結果が大きくなりすぎるから)
ここでは,以下の3つの方法を検討し,それぞれ生成処理に要した時間も記録する。
- ランダムな内容の巨大データを,データベース上に作成
- ランダムな内容の巨大ファイルを,ファイルシステム上に作成
- 均質な内容の巨大ファイルを,ファイルシステム上に作成
(1)ランダムな内容の巨大データを,データベース上に作成
データベース(PostgreSQL)内に,巨大データを登録する。
そこでpg_dumpすれば,指定したサイズ(を上回るサイズ)の巨大なファイルが得られる。
ストアドファンクションを使えば,forループ内でINSERT文を繰り返し発行できて楽だ。
下記のSQLを実行。
-- 10000件のダミーレコードを登録する CREATE OR REPLACE FUNCTION create_big_data() RETURNS bool AS $$ DECLARE char_random char(1); str_value varchar(10); str_sql varchar(200); BEGIN -- INSERT文を繰り返し発行 FOR i IN 1..10000 LOOP -- 10バイトのデータを作成 str_value = ''; FOR j IN 1..10 LOOP -- ランダムな1文字の数字を取得 SELECT ceiling( random() * 10 ) - 1 INTO char_random ; -- 結合 str_value = str_value || char_random; END LOOP; -- SQL文を作成 str_sql = 'INSERT INTO hoge_table( fuga_column ) VALUES (' || '''' || str_value || '''' || ');' ; -- SQLを実行 EXECUTE str_sql; END LOOP; RETURN true; END; $$ LANGUAGE plpgsql ; -- 実行する SELECT create_big_data();
これで,10バイトのレコードが10000件作成される。
計100kBと見て,実行に2秒ほどかかった。
これでpg_dumpすれば,「内容が均質でない巨大データ」をファイルとして取得できる。
なお,PL/pgSQLの導入方法と基礎文法は下記を参照。
PREPARE文と,PL/pgSQL の入門 (PostgreSQLで「動的に」SQLを実行するために,プリペアド・クエリやストアドファンクションを定義しよう)
http://language-and-engineering.hatenablog.jp/entry/20110218/p1
(2)ランダムな内容の巨大ファイルを,ファイルシステム上に作成
直接,ファイルとして巨大なデータを書き込む。
hoge.sh
#!/bin/sh target_dir="/tmp" target_file="${target_dir}/big_data" # 初期化 rm -f ${target_file} touch ${target_file} # 書き込み echo "started at $(date)" for ((i=0; i<10000; i++)) do # 10バイト分 printf "%05d" ${RANDOM} >> ${target_file} printf "%05d" ${RANDOM} >> ${target_file} done echo "end at $(date)" # 終了 ls -l ${target_dir}
100kBで2秒かかった。
速度は,DB上に登録するのと大差ない。
補足:
- bashのfor文の記述方法として,「算術演算forループ」を利用している。
- $RANDOMは組み込み変数で,5桁までの乱数を返す。
- ランダムな数字の並びを5バイト分確保するために,printfで乱数を0埋めしてフォーマットをそろえている。
なお,成果物がASCIIテキストでなくてもよいのであれば,ランダムなバイナリを生成するために下記のコマンドを実行できる。
-- 1GBのランダムなバイナリを作成 head -c 1000m /dev/urandom > /tmp/big_data
/dev/urandomは,ランダムなビット列を比較的高速に生成するデバイスファイル。
これだと,1GBのファイル生成に5分かかる。
こいつをgzipすると,逆にファイルサイズが大きくなる。
最初から最後まで,ビット単位で機械的なランダム性を持っているため,圧縮のしようがないのだ。
なので,この方法は,gzipに渡すためのテストファイルとしては利用できない。
中身がランダムなファイルを任意のサイズで作成する
http://kazmax.zpp.jp/linux/random_fil...
/dev/random と /dev/urandom の違い
http://kaworu.jpn.org/kaworu/2010-11-...
(3)均質な内容の巨大ファイルを,ファイルシステム上に作成
前述の方法は,いずれも「ファイルの内容が均質でないようにする」という制限があった。
その制限がなければ,巨大なファイルを作るのは楽。
ddコマンドを使う。
# 1GBのファイルを作成 dd if=/dev/zero of=/tmp/big_data bs=1M count=1024
1GBのダミーファイルを作成するのに20秒かかった。前述の方法よりずっと速い。
容量指定のダミーファイルを作成したい
http://www.itmedia.co.jp/help/tips/li...
なお,ファイルの内容が均質なので,gzipで圧縮すると1メガになってしまう。