以下的做法整理自論壇上的帖子。
如何create大檔案
要大就非常大,1t吧。
有兩種方法:
一.dd
dd if=/dev/zero of=1t.img bs=1g seek=1024 count=0
bs=1g表示每一次讀寫1g資料,count=0表示讀寫0次,seek=1024表示略過1024個block不寫,前面block size是1g,所以共略過1t!
這是建立大型sparse檔案最簡單的方法。
二.ftruncate64/ftruncate
如果用系統函式就稍微有些麻煩,因為涉及到巨集的問題。我會結合乙個實際例子詳細說明,其中option標誌的就是測試項。
檔案sparse.c:
//option 1:是否定義與大檔案相關的巨集
#define _largefile_source
#define _largefile64_source
#define _file_offset_bits 64
#include
#include
#include
#include
#include
#include
#define filename "bigfile"
#define file_mode (s_irusr | s_iwusr | s_irgrp | s_iroth)
int main(int argc, char **argv)
//option 2:是否有o_largefile選項
//fd = open(filename, o_rdwr|o_creat|o_largefile, 0644);
fd = open(filename, o_rdwr|o_creat, 0644);
if (fd < 0)
offset = (off_t)total *1024ll*1024ll*1024ll;
printf("offset=%ld/n", offset);
//option 3:是否呼叫64位系統函式
//if (ftruncate64(fd, offset) < 0)
if (ftruncate(fd, offset) < 0)
close(fd);
printf("ok/n");
return 0;
}測試環境:
linux:/disk/test/big # gcc --version
gcc (gcc) 3.3.5 20050117 (prerelease) (suse linux)
linux:/disk/test/big # uname -a
linux linux 2.6.11.4-20a-default #1 wed mar 23 21:52:37 utc 2005 i686 i686 i386 gnu/linux
測試結果(偽碼表示):
1.巨集定義完全的情況下:
if ok;
elseif
ok;elseif
執行不報錯,但是不支援》4g;
elseif
執行不報錯,但是不支援》4g;
【結論】:在巨集定義完全的情況下,是否呼叫ftruncate64,是決定支援4g以上檔案的關鍵,o_largefile無作用。
2.巨集定義不完全:缺少_file_offset_bits
首先宣告一點,o_largefile需要定義_largefile64_source。
if 產生不正常超大檔案;
elseif
產生不正常超大檔案;
elseif
執行不報錯,但是不支援》2g;
elseif
執行不報錯,但是不支援》4g;
【結論】:未定義_file_offset_bits的情況下,ftruncate64呼叫是非法的,會產生無法預料的後果,這裡的測試就是產生乙個超大檔案(>1t),我也無法解釋其原因;o_largefile的作用就是在32位系統中支援大檔案系統,允許開啟那些用31位(2g)都不能表示其長度的大檔案;此外,off_t為unsigned int型別,也就是說最多只能達到4g,所以ftruncate最大支援4g檔案。
總結一下:如果要支援超過2g的檔案,至少需要定義_largefile64_source巨集,並且設定o_largefile選項;如果要支援超過4g,需要定義所有上述的巨集,並且呼叫ftruncate64;其餘的搭配都是錯誤的!
【附】:
dd 的主要選項:
指定數字的地方若以下列字元結尾乘以相應的數字:
b=512, c=1, k=1024, w=2, m=1024k, g=1024m
大小寫不限。
if=file
輸入檔名,預設為標準輸入。
of=file
輸出檔名,預設為標準輸出。
ibs=bytes
一次讀入 bytes 個位元組(即乙個塊大小為 bytes 個位元組)。
obs=bytes
一次寫 bytes 個位元組(即乙個塊大小為 bytes 個位元組)。
bs=bytes
同時設定讀寫塊的大小為 bytes ,可代替 ibs 和 obs 。
cbs=bytes
一次轉換 bytes 個位元組,即轉換緩衝區大小。
skip=blocks
從輸入檔案開頭跳過 blocks 個塊後再開始複製。
seek=blocks
從輸出檔案開頭跳過 blocks 個塊後再開始複製。(通常只有當輸出檔案是磁碟或磁帶時才有效)
count=blocks
僅拷貝 blocks 個塊,塊大小等於 ibs 指定的位元組數。
conv=conversion[,conversion...]
用指定的引數轉換檔案。
轉換引數:
ascii 轉換 ebcdic 為 ascii。
ebcdic 轉換 ascii 為 ebcdic。
ibm 轉換 ascii 為 alternate ebcdic.
block 把每一行轉換為長度為 cbs 的記錄,不足部分用空格填充。
unblock
使每一行的長度都為 cbs ,不足部分用空格填充。
lcase 把大寫字元轉換為小寫字元。
ucase 把小寫字元轉換為大寫字元。
noerror
不顯示錯誤
notrunc
不截短輸出檔案。
sync 把每個輸入塊填充到ibs個位元組,不足部分用空(nul)字元補齊。
C 利用Stream讀寫大檔案
在日常生活中,可能會遇到大檔案的讀取,不論是什麼格式,按照儲存檔案的格式讀取大檔案,就會在buffer中看到相關的檔案頭合內容,以一次.txt檔案訪問為例。using system.io private void button2 click object sender,eventargs e byt...
Linux下查詢大檔案,大目錄的方法
列舉出當前目錄所有大於800m的檔案 find type f size 800m 第乙個方法只用到了乙個命令find,它能夠幫我們做一些檔案查詢的操作。它常用的引數有 type 型別。posix支援 b 塊裝置文件 d 目錄 c 字元裝置文件 p 管道文件 l 符號鏈結文件 f 普通文件 name ...
linux下建立大檔案
在linux下建立大檔案可用dd命令 dd if dev zero of hello.txt bs 100m count 1 或 dd if dev zero of hello.txt bs 1k count 1024000 上面這個命令在i當前目錄產生了乙個100m的測試檔案hello.txt。改...