正常32位機器開啟大於2g的檔案會報錯,解決辦法:
一、定義巨集
// 定義巨集,使得可以處理大檔案(>4gb)
#undef _file_offset_bits
#define _file_offset_bits 64
#include
二、在makefile編譯選項裡加上-d_file_offset_bits=64 -d_large_file
三、使用fopen64函式
---------------------------------------
1、gcc 加 -d_file_offset_bits=64 -d_large_file
2、注意一定要定義在include之前
#define _largefile_source
#define _largefile64_source
#define _file_offset_bits 64
建議兩種方式都加上。
如何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)字元補齊。
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。改...
檔案操作 linux快速建立大檔案的方法
還記得去年在準備某公司的筆試時遇到了一道題目,題目中要求 快速建立1g的大檔案 後面的要求這裡暫且就省略了。如何快速建立指定大小的大檔案呢?可能有很多種辦法,這裡提供兩種辦法。1 利用dd命令操作建立檔案 結合c語言,可以使用system函式呼叫shell命令 char shell dd if de...
linux 分割大檔案
你曾經是否想要把乙個大檔案分割成多個小檔案?比如乙個5gb日誌檔案,我們需要把它分成多個小檔案,這樣我們才有可能使用普通的文字編輯器讀取它。有時我們需要傳輸20gb的大檔案到另一台伺服器,這就需要我們把它分割成多個檔案,這樣便於傳輸資料。下面我們來通過五個例項來講解它。split命令分割檔案成每個檔...