版權聲明:本文由胡恆威原創文章,轉載請注明出處:
文章原文鏈接:https://www.qcloud.com/community/article/86
來源:騰雲閣 https://www.qcloud.com/community
是否會有這樣的場景:在有需要測試數據的時候,你不知如何生成一些已包含測試數據的文件;或者你是臨時需要一個小的程序,可以讓你生成不同大小的文件(比如大於1Mb少於100Mb),不需要從網絡上去搜尋查找如何生成,這里有一些簡單的方法幫你偷懶。
1.當你不需要關心隨機文件的內容,只需一個固定大小的文件
-
Solaris、Mac OS X等Unix系統中mkfile指令,可以產生指定大小的文件,而Linux上則沒有
例子:mkfile -n 160g test1
-
Linux可以用dd指令,/dev/zero是一個特別的文件描述符可以通過它返回null值
例子:dd if=/dev/zero of=test.file count=1024 bs=1024
產生count * bs字節的文件,1M
此方法生成隨機文件的好處在於效率高(產生1G文件大概1s),創建的文件大小精確到字節
壞處也有
使用null字符來填充文件內容,文件統計時沒有行(wc -l test.file
為0)
2.當你不需要關心隨機文件的內容,但期望測試文件能有統計的行
將/dev/zero
改為/dev/urandom
,/dev/urandom
是linux下的隨機數生成器
關於/dev/urandom
跟/dev/random
兩者的區別就不在此詳細討論,大概就是,前者是不受系統interrupts
的限制,即使沒有足夠的interrupt它也能通過隨機數生成器產生足夠的輸出值;而后者如果用在dd
上,它不能被ctrl+c
或者kill -9
中斷,如果ds的值較大時,產生的隨機值不足而長期占用CPU。雖然說/dev/random
產生的隨機數會更隨機些,但與dd混用還是建議用/dev/urandom
效率更高。
缺點跟/dev/zero
比當然是效率會更低些了,生成個100Mb的文件需要10秒左右,而且文件並沒有可讀的內容,一般的情況基本上是滿足了。
漏了說句,dd
是linux與unix都支持的指令。
3.當你關心文件的隨機內容行數,而不關心內容是否有所重復
這里的思路就是找一個參照文件(比如說2行),將文件重新定向到新的文件,再mv覆蓋保存,外加一個for循環。(n為循環次數,產生的文件行為2^(n+1))
例子:假設先建立一個file.txt文件,里面含有Hello 和 World兩行for i in {1..n}; do cat file.txt file.txt > file2.txt && mv file2.txt file.txt; done
由於是階乘,n=20左右已經是200W行,效率會下降地比較厲害
4.當你關心隨機文件的內容,而不想出現重復內容行情況
這種情況下系統的指令應該是不能滿足了,或者可以通過操作系統的指令寫一大串腳本也可以達到,但不建議這么做,因為可讀性和維護性考慮,你應該要引入Ruby或者Python類的腳本語言幫忙了
但還是要借助些系統的東西來幫忙
思路:/usr/share/dict/words
里面有記錄一些單詞,一共235886行,每行一個單詞
可以從里面挑選一些作為文件的內容
加循環達到我們想要的隨機文件要求
舉例:ruby -e 'a=STDIN.readlines;X.times do; b=[];Y.times do; b<<a[rand(a.size)].chomp end; puts b.join(" ")' < /usr/share/dict/words > file.txt
X為隨機文件需要的行數,Y為從words中讀取的單詞,雖說組合成一句的命令,還是可以讀懂的;從標准輸入中重復讀取Y個單詞,寫入到b列表中,然后再通過join空格連接內容寫入到標准輸出文件file.txt中
這樣基本很少會有重復的行了,而且生成的效率與其他方法對比還是可以的,10秒生成100Mb文件。歡迎大家討論。
參考:
mkfile的Apple官方文檔:
https://developer.apple.com/library/mac/documentation/Darwin/Reference/Manpages/man8/mkfile.8.html
dd的wiki:
http://en.wikipedia.org/wiki/Dd_(Unix)