在我們日常工作中,為了驗證開發的功能,比如:文件上傳功能或者演算法的處理效率等,經常需要一些大文件進行測試,有時在四處找了一頓之後,發現竟然沒有一個合適的,雖然 Linux 中也有一些命令比如:vim、touch 等可以創建文件,但是如果需要一個 100G 或者 1T 的大文件,這些命令就顯得力不從心 ...
在我們日常工作中,為了驗證開發的功能,比如:文件上傳功能或者演算法的處理效率等,經常需要一些大文件進行測試,有時在四處找了一頓之後,發現竟然沒有一個合適的,雖然 Linux 中也有一些命令比如:vim、touch
等可以創建文件,但是如果需要一個 100G 或者 1T 的大文件,這些命令就顯得力不從心,此時就需要能快速創建大文件命令,接下來將介紹這些命令的常見用法、命令之間的差異、以及使用時如何選擇
dd
dd
命令的語法如下
dd if=[source] of=[destination] bs=[block-size] count=[counter]
從 source
讀取並拷貝內容到 destination
, source
和 destination
都是文件,前者是讀取的文件,後者是寫入的文件
bs
表示塊的大小,單位是位元組,尾碼中帶了字母 B
的換算單位都是 1000
, 比如: 1KB = 1000 Bytes
、 1MB = 1000 * 1000 Bytes
、 1GB = 1000 * 1000 * 1000 Bytes
尾碼省略了字母 B
的換算單位是 1024
, 比如: 1K = 1024 Bytes
、 1M = 1024 * 1024 Bytes
、 1G = 1024 * 1024 * 1024 Bytes
count
表示塊的數量,表示 dd
命令需要執行多少次讀取並寫入的操作
bs
乘以 count
其實就表示目標文件的大小,也即需要創建的文件的大小,比如:下麵的命令可以創建一個 10G 大小的文件
[root@localhost dd_cmd]# dd if=/dev/zero of=testfile bs=1G count=10
記錄了10+0 的讀入
記錄了10+0 的寫出
10737418240位元組(11 GB)已複製,8.61643 秒,1.2 GB/秒
[root@localhost dd_cmd]# du -h testfile
10G testfile
[root@localhost dd_cmd]#
上面的命令表示從 /dev/zero
文件每次讀取 1G
大小的數據並寫入當前目錄中的 testfile
文件, bs=1G count=10 表示塊大小是1G
,總共有10個塊, 所以目標文件最終的大小是: 1G * 10 = 10G
/dev/zero
是一個特殊的字元設備文件,當讀取它的時候,它會返回空數據,這裡表示從 /dev/zero
讀取空的數據寫入 testfile
中
命令 du -h testfile
的結果也說明瞭 testfile
大小是 10G
從結果可以得知,用 dd
命令創建一個 10G
大小的文件花費了約 8.6 秒
yes
前面的 dd
命令創建的是空字元的文件,如果想文件中包含自定義的字元,可以使用 yes
命令,它的作用是迴圈輸出一行指定的字元串,直到進程結束,為了控制文件的大小並打破迴圈,我們藉助 head
命令來實現,使用 yes
命令創建包含指定內容文件的語法如下
yes [string] | head -c [size of file] > [name of file]
string
是寫入文件每一行的字元串
head -c [size of file]
是接收指定大小的字元串,單位是位元組,後面也可以接 K
、KB
、M
、MB
、G
、GB
等單位
下麵的實例是往 yesfile
文件寫入,每行的內容是: this is a test content
, 一直到文件大小達到 10G
[root@localhost dd_cmd]# time yes "this is a test content" | head -c 10G > yesfile
real 0m11.266s
user 0m8.898s
sys 0m13.217s
[root@localhost dd_cmd]# du -h yesfile
10G yesfile
從結果可以看出,yes
命令創建一個 10G
的文件花費了 13.2 秒,比 dd
命令慢
fallocate
fallocate
命令使用下麵的語法 創建大文件
fallocate -l [size of file] [name of file]
-l
選項表示文件大小,單位是位元組,後面可以接 K
、KB
、M
、MB
、G
、GB
等單位
下麵的命令是創建一個 10G
大小的文件
[root@localhost dd_cmd]# time fallocate -l 10G allocatefile
real 0m0.002s
user 0m0.000s
sys 0m0.003s
[root@localhost dd_cmd]# du -h allocatefile
10G allocatefile
上述的 time
命令只是為了統計創建文件的時間,從結果可以看出:fallocate
命令創建一個 10G
大小的文件竟然只花費了 0.003 秒
命令 du -h allocatefile
是查看創建的文件大小,從結果可知,allocatefile
文件大小確實是 10G
truncate
truncate
命令是縮小或者擴展文件至指定大小,它的語法如下:
truncate -s [file-size] [name of the file]
-s
選項表示文件大小,單位是位元組,跟 fallocate
命令一樣,後面可以接 K
、KB
、M
、MB
、G
、GB
等單位
下麵是使用 truncate
命令創建一個 10G
的文件的示例
[root@localhost dd_cmd]# time truncate -s 10G truncatefile
real 0m0.002s
user 0m0.000s
sys 0m0.002s
[root@localhost dd_cmd]# du -h truncatefile
0 truncatefile
從結果可以得到,truncate
命令 創建一個 10G
的文件也只花費了 0.002 秒,和 fallocate
差不多
但是, du -h truncatefile
命令的結果表明 truncatefile
大小為 0
原因是 truncate 命令 創建的是一個稀疏文件而不是實際的文件 ,稀疏文件不會占用磁碟空間
註意:fallocate
命令只支持 btrfs、ext4、 ocfs2、xfs
這幾種文件系統,而 truncate
命令支持所有的現代文件系統
創建速度的差異
從上面的幾個實例可以看出,同樣是創建一個 10G
的文件, fallocate
和 truncate
命令只需要不到 0.1 秒的時間,但是 dd
命令需要 8.6 秒的時間,yes
命令需要 13.2 秒,這中間相差了幾百倍,為什麼會有這麼大的差別呢?
fallocate
將空間分配給文件,但是不會往文件中寫入任何數據
truncate
創建的是稀疏文件,和 fallocate
一樣,它也不會往文件中寫入任何數據
dd
和 yes
都有寫文件操作,而這需要大量的 IO 時間,所以同樣創建 10G
的文件,它們比 fallocate
和 truncate
要慢很多
如何選擇
dd
、yes
、fallocate
、truncate
這幾個命令都可以創建大文件, 在日常的使用中,我們該如何選擇呢 ?
對速度沒有很高的要求的情況下,一般首選 dd
,如果希望創建的文件中寫入自定義的內容的話,使用 yes
如果想快速的創建大文件,比如 1 秒內創建一個 100G 的文件,選擇 fallocate
和 truncate
,如果還需要確保文件是實際占用磁碟空間的話,就只剩下 fallocate
可選了
大部分情況下,fallocate
都能滿足要求,所以不想仔細分析的話,使用 fallocate
就行了
小結
本文介紹了Linux下創建大文件的幾種方法,並對所提供的方法進行了比較,最後提供瞭如何選擇使用哪種方法的一些建議,文中只對 dd
、yes
、fallocate
、truncate
命令做了簡要的說明,更多的介紹請參考 man
文檔