linux c 大文件使用

本文介绍了两种创建大于4GB的大文件的方法:使用dd命令通过跳过大量数据块来创建稀疏文件,以及通过C语言编程利用ftruncate64系统调用来实现。文章还详细探讨了在32位系统上支持大文件所需的宏定义及选项。

转帖:http://hi.baidu.com/roxws/blog/item/785c4bcb61662ff853664f2d.html

----------------------------------------------------------------------------------------

支持大文件的两种方式:

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 <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 --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;
结论】:在宏定义完全的情况下,是否调用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)字符补齐。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值