Linux大文件使用

http://blog.csdn.net/lsk_30516/article/details/4201599

支持大文件的两种方式:

1、gcc 加 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE

2、注意一定要定义在include之前

#define _LARGEFILE_SOURCE#define _LARGEFILE64_SOURCE#define _FILE_OFFSET_BITS 64

建议两种方式都加上。

可以在GDB调试时打印p sizeof(off_t)来确定设置是否成功

如果值为8 成功

如果值为4 定义没有成功

如何create大文件要大就非常大,1T吧。有两种方法:一.dddd if=/dev/zero of=1T.img bs=1G seek=1024 count=0bs=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 <stdio.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;int total = 0;if ( argc >= 2 ){total = atol(argv[1]);printf("total=%d/n", total);}//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) {perror(FILENAME);return -1;}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){printf("[%d]-ftruncate64 error: %s/n", errno, strerror(errno));close(fd);return 0;}close(fd);printf("OK/n");return 0;}测试环境:linux:/disk/test/big # gcc –versiongcc (GCC) 3.3.5 20050117 (prerelease) (SUSE Linux)linux:/disk/test/big # uname -aLinux 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;【结论】:在宏定义完全的情况下,是否调用ftruncate64,是决定支持4G以上文件的关键,O_LARGEFILE无作用。2.宏定义不完全:缺少_FILE_OFFSET_BITS首先声明一点,O_LARGEFILE需要定义_LARGEFILE64_SOURCE。IF {O_LARGEFILE=TRUE && ftruncate64=TRUE}产生不正常超大文件;ELSEIF {O_LARGEFILE=FALSE && ftruncate64=TRUE}产生不正常超大文件;ELSEIF {O_LARGEFILE=FALSE && ftruncate64=FALSE}运行不报错,但是不支持>2G;ELSEIF {O_LARGEFILE=TRUE && ftruncate64=FALSE}运行不报错,但是不支持>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大文件使用

相关文章:

你感兴趣的文章:

标签云: