-

- 加为好友
- 发送私信
- 在线聊天
freshui
- 等级:

- 可用分等级:
- 总技术分:
- 总技术分排名:
-
|
| 发表于:2008-11-04 18:05:094楼 得分:10 |
如何create大文件 (2006-08-08 12:26:00) 如何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)字符补齐。 | | |
修改
删除
举报
引用
回复
| |