支持大文件的兩種方式:
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數(shù)據(jù),count=0表示讀寫0次,seek=1024表示略過1024個Block不寫,前面block size是1G,所以共略過1T!
這是創(chuàng)建大型sparse文件最簡單的方法。
dd if=/dev/zero of=1T.img bs=1G seek=1024 count=0
bs=1G表示每一次讀寫1G數(shù)據(jù),count=0表示讀寫0次,seek=1024表示略過1024個Block不寫,前面block size是1G,所以共略過1T!
這是創(chuàng)建大型sparse文件最簡單的方法。
二.ftruncate64/ftruncate
如果用系統(tǒng)函數(shù)就稍微有些麻煩,因為涉及到宏的問題。我會結合一個實際例子詳細說明,其中OPTION標志的就是測試項。
文件sparse.c:
如果用系統(tǒng)函數(shù)就稍微有些麻煩,因為涉及到宏的問題。我會結合一個實際例子詳細說明,其中OPTION標志的就是測試項。
文件sparse.c:
//OPTION 1:是否定義與大文件相關的宏
#define _LARGEFILE_SOURCE
#define _LARGEFILE64_SOURCE
#define _FILE_OFFSET_BITS 64
#define _LARGEFILE_SOURCE
#define _LARGEFILE64_SOURCE
#define _FILE_OFFSET_BITS 64
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#define FILENAME "bigfile"
#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
int main(int argc, char **argv)
{
int fd, ret;
off_t offset;
#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
int main(int argc, char **argv)
{
}
測試環(huán)境:
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
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 {O_LARGEFILE=TRUE && ftruncate64=TRUE}
OK;
ELSEIF {O_LARGEFILE=FALSE && ftruncate64=TRUE}
OK;
ELSEIF {O_LARGEFILE=FALSE && ftruncate64=FALSE}
運行不報錯,但是不支持>4G;
ELSEIF {O_LARGEFILE=TRUE && ftruncate64=FALSE}
運行不報錯,但是不支持>4G;
【結論】:在宏定義完全的情況下,是否調(diào)用ftruncate64,是決定支持4G以上文件的關鍵,O_LARGEFILE無作用。
1.宏定義完全的情況下:
IF {O_LARGEFILE=TRUE && ftruncate64=TRUE}
ELSEIF {O_LARGEFILE=FALSE && ftruncate64=TRUE}
ELSEIF {O_LARGEFILE=FALSE && ftruncate64=FALSE}
ELSEIF {O_LARGEFILE=TRUE && ftruncate64=FALSE}
【結論】:在宏定義完全的情況下,是否調(diào)用ftruncate64,是決定支持4G以上文件的關鍵,O_LARGEFILE無作用。
2.宏定義不完全:缺少_FILE_OFFSET_BITS
首先聲明一點,O_LARGEFILE需要定義_LARGEFILE64_SOURCE。
IF {O_LARGEFILE=TRUE && ftruncate64=TRUE}
產(chǎn)生不正常超大文件;
ELSEIF {O_LARGEFILE=FALSE && ftruncate64=TRUE}
產(chǎn)生不正常超大文件;
ELSEIF {O_LARGEFILE=FALSE && ftruncate64=FALSE}
運行不報錯,但是不支持>2G;
ELSEIF {O_LARGEFILE=TRUE && ftruncate64=FALSE}
運行不報錯,但是不支持>4G;
【結論】:未定義_FILE_OFFSET_BITS的情況下,ftruncate64調(diào)用是非法的,會產(chǎn)生無法預料的后果,這里的測試就是產(chǎn)生一個超大文件(>1T),我也無法解釋其原因;O_LARGEFILE的作用就是在32位系統(tǒng)中支持大文件系統(tǒng),允許打開那些用31位(2G)都不能表示其長度的大文件;此外,off_t為unsigned int類型,也就是說最多只能達到4G,所以ftruncate最大支持4G文件。
首先聲明一點,O_LARGEFILE需要定義_LARGEFILE64_SOURCE。
IF {O_LARGEFILE=TRUE && ftruncate64=TRUE}
ELSEIF {O_LARGEFILE=FALSE && ftruncate64=TRUE}
ELSEIF {O_LARGEFILE=FALSE && ftruncate64=FALSE}
ELSEIF {O_LARGEFILE=TRUE && ftruncate64=FALSE}
【結論】:未定義_FILE_OFFSET_BITS的情況下,ftruncate64調(diào)用是非法的,會產(chǎn)生無法預料的后果,這里的測試就是產(chǎn)生一個超大文件(>1T),我也無法解釋其原因;O_LARGEFILE的作用就是在32位系統(tǒng)中支持大文件系統(tǒng),允許打開那些用31位(2G)都不能表示其長度的大文件;此外,off_t為unsigned int類型,也就是說最多只能達到4G,所以ftruncate最大支持4G文件。
總結一下:如果要支持超過2G的文件,至少需要定義_LARGEFILE64_SOURCE宏,并且設置O_LARGEFILE選項;如果要支持超過4G,需要定義所有上述的宏,并且調(diào)用ftruncate64;其余的搭配都是錯誤的!
【附】:
dd 的主要選項:
指定數(shù)字的地方若以下列字符結尾乘以相應的數(shù)字:
b=512, c=1, k=1024, w=2, m=1024k, g=1024m
大小寫不限。
dd 的主要選項:
指定數(shù)字的地方若以下列字符結尾乘以相應的數(shù)字:
b=512, c=1, k=1024, w=2, m=1024k, g=1024m
大小寫不限。
if=file
輸入文件名,缺省為標準輸入。
輸入文件名,缺省為標準輸入。
of=file
輸出文件名,缺省為標準輸出。
輸出文件名,缺省為標準輸出。
ibs=bytes
一次讀入 bytes 個字節(jié)(即一個塊大小為 bytes 個字節(jié))。
一次讀入 bytes 個字節(jié)(即一個塊大小為 bytes 個字節(jié))。
obs=bytes
一次寫 bytes 個字節(jié)(即一個塊大小為 bytes 個字節(jié))。
一次寫 bytes 個字節(jié)(即一個塊大小為 bytes 個字節(jié))。
bs=bytes
同時設置讀寫塊的大小為 bytes ,可代替 ibs 和 obs 。
同時設置讀寫塊的大小為 bytes ,可代替 ibs 和 obs 。
cbs=bytes
一次轉(zhuǎn)換 bytes 個字節(jié),即轉(zhuǎn)換緩沖區(qū)大小。
一次轉(zhuǎn)換 bytes 個字節(jié),即轉(zhuǎn)換緩沖區(qū)大小。
skip=blocks
從輸入文件開頭跳過 blocks 個塊后再開始復制。
從輸入文件開頭跳過 blocks 個塊后再開始復制。
seek=blocks
從輸出文件開頭跳過 blocks 個塊后再開始復制。(通常只有當輸出文件是磁盤或磁帶時才有效)
從輸出文件開頭跳過 blocks 個塊后再開始復制。(通常只有當輸出文件是磁盤或磁帶時才有效)
count=blocks
僅拷貝 blocks 個塊,塊大小等于 ibs 指定的字節(jié)數(shù)。
僅拷貝 blocks 個塊,塊大小等于 ibs 指定的字節(jié)數(shù)。
conv=conversion[,conversion...]
用指定的參數(shù)轉(zhuǎn)換文件。
用指定的參數(shù)轉(zhuǎn)換文件。
轉(zhuǎn)換參數(shù):
ascii 轉(zhuǎn)換 EBCDIC 為 ASCII。
ebcdic 轉(zhuǎn)換 ASCII 為 EBCDIC。
ibm 轉(zhuǎn)換 ASCII 為 alternate EBCDIC.
block 把每一行轉(zhuǎn)換為長度為 cbs 的記錄,不足部分用空格填充。
unblock
使每一行的長度都為 cbs ,不足部分用空格填充。
使每一行的長度都為 cbs ,不足部分用空格填充。
lcase 把大寫字符轉(zhuǎn)換為小寫字符。
ucase 把小寫字符轉(zhuǎn)換為大寫字符。
noerror
不顯示錯誤
不顯示錯誤
notrunc
不截短輸出文件。
不截短輸出文件。
sync 把每個輸入塊填充到ibs個字節(jié),不足部分用空(NUL)字符補齊。
from:
http://hi.baidu.com/roxws/blog/item/785c4bcb61662ff853664f2d.html/cmtid/f990c324dee21627d50742e9
from:
http://hi.baidu.com/roxws/blog/item/785c4bcb61662ff853664f2d.html/cmtid/f990c324dee21627d50742e9