linux创建大文件

正常32位机器打开大于2G的文件会报错,解决办法:
一、定义宏 
//   定义宏,使得可以处理大文件(>4GB)    
#undef   _FILE_OFFSET_BITS    
#define   _FILE_OFFSET_BITS   64    
#include   <unistd.h>    
#include   <dirent.h>
 
二、在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 <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)字符补齐。




inux 中的Too many open file要如何解决 ?

linux as 3,内核2.4。服务经常出现Too many open file错误!那么如何调整“操作系统的中打开文件的最大句柄数”?  

/proc/sys/kernel/file-max,要永久生效需修改/etc/sysctl.conf 
随便baidu了一下 

使用/proc文件系统来控制系统 
/proc/sys/fs 
/proc/sys/fs/file-max 
该文件指定了可以分配的文件句柄的最大数目。如果用户得到的错误消息声明由于打开文件数已经达到了最大值,从而他们不能打开更多文件,则可能需要增加该值。可将这个值设置成有任意多个文件,并且能通过将一个新数字值写入该文件来更改该值。 

缺省设置:4096 

/proc/sys/fs/file-nr 
该文件与 file-max 相关,它有三个值:  
已分配文件句柄的数目 
已使用文件句柄的数目 
文件句柄的最大数目 
该文件是只读的,仅用于显示信息。 

所以不存在两个文件的配合修改问题,主要修改file-max就行了 

3. ulimit -a中 
open files                    (-n) 1024 

也即是ulimit -n 

-n     The maximum number of open file descriptors (most systems 
do not allow this value to be set) 

ulimit -n  设置用户可以同时打开的最大文件数(max open files)  

例如:ulimit -n 8192     

如果本参数设置过小,对于并发访问量大的网站,可能会出现too many open files的错误   



我看一些文章,建议在/etc/rc.d/rc.local中修改/proc/sys/fs/file-max、/proc/sys/fs/file-nr的内容 
cat /proc/sys/fs/file-max 
209695 

cat  /proc/sys/fs/file-nr 
4483    3550    209695 

请问这2个文件要如何配合修改? 

3。采用ulimit -a出现如下描述 

$ulimit -a 

core file size        (blocks, -c) 0 
data seg size         (kbytes, -d) unlimited 
file size             (blocks, -f) unlimited 
max locked memory     (kbytes, -l) 4 
max memory size       (kbytes, -m) unlimited 
open files                    (-n) 1024 
pipe size          (512 bytes, -p) 8 
stack size            (kbytes, -s) 10240 
cpu time             (seconds, -t) unlimited 
max user processes            (-u) 7168 
virtual memory        (kbytes, -v) unlimited 

其中的open files与上面现象有关系呢?


Too many open files 问题出现有两种情况: 
一种是在搜索的时候出现,多半是由于索引创建完毕之后被移动过,如果创建索引的时候不出现该错误,搜索的时候也一般是不会出现的。如果出现了,有两种处理办法,一种是修改合并因子和最小合并因子,并且使用 
IndexWriter.Optimize() 优化索引,这样会将索引文件数量减少到文件系统限制之内;另外一种办法是修改操作系统的打开文件数量限制。方法如下: 
1. 按照最大打开文件数量的需求设置系统, 并且通过检查/proc/sys/fs/file-max文件来确认最大打开文件数已经被正确设置。  
# cat /proc/sys/fs/file-max 
如果设置值太小, 修改文件/etc/sysctl.conf的变量到合适的值。 这样会在每次重启之后生效。 如果设置值够大,跳过下步。  
# echo 2048 > /proc/sys/fs/file-max 
编辑文件/etc/sysctl.conf,插入下行。  
fs.file-max = 8192 
2. 在/etc/security/limits.conf文件中设置最大打开文件数, 下面是一行提示:  
#  
添加如下这行。  
* - nofile 8192 
这行设置了每个用户的默认打开文件数为2048。 注意"nofile"项有两个可能的限制措施。就是项下的hard和soft。 要使修改过得最大打开文件数生效,必须对这两种限制进行设定。 如果使用"-"字符设定, 则hard和soft设定会同时被设定。  
硬限制表明soft限制中所能设定的最大值。 soft限制指的是当前系统生效的设置值。 hard限制值可以被普通用户降低。但是不能增加。 soft限制不能设置的比hard限制更高。 只有root用户才能够增加hard限制值。  
当增加文件限制描述,可以简单的把当前值双倍。 例子如下, 如果你要提高默认值1024, 最好提高到2048, 如果还要继续增加, 就需要设置成4096。  
另外一种情况是在创建索引的时候,也有两种可能,一种是 合并因子太小,导致创建文件数量超过操作系统限制,这时可以修改合并因子,也可以修改操作系统的打开文件数限制;另外一种是合并因子受虚拟机内存的限制,无法调整到更大,而 需要索引的doc 数量又非常的大,这个时候就只能通过修改操作系统的打开文件数限制来解决了。  
在此基础上,我还修改了以下一个配置文件 
vi /etc/sysctl.conf  
添加: 
# Decrease the time default value for tcp_fin_timeout connection 
net.ipv4.tcp_fin_timeout = 30 
# Decrease the time default value for tcp_keepalive_time connection 
net.ipv4.tcp_keepalive_time = 1800 
# Turn off tcp_window_scaling 
net.ipv4.tcp_window_scaling = 0 
# Turn off the tcp_sack 
net.ipv4.tcp_sack = 0 
#Turn off tcp_timestamps 
net.ipv4.tcp_timestamps = 0 
然后 service network restart,这些都和TCP sockets有关的优化。 
另外需要在 /etc/rc.d/rc.local里添加已使得重启的时候生效。 
echo "30">/proc/sys/net/ipv4/tcp_fin_timeout 
echo "1800">/proc/sys/net/ipv4/tcp_keepalive_time 
echo "0">/proc/sys/net/ipv4/tcp_window_scaling 
echo "0">/proc/sys/net/ipv4/tcp_sack 
echo "0">/proc/sys/net/ipv4/tcp_timestamps 
因为不是所有的程序都在root下跑的,所有linux有对hard 与soft open files 的区分,普通用户受hard的限制,无论ulimit -n $数值调到多高,都跑不到 /etc/security/limits.conf里nofile的值. 
这样的优化后 lsof -p $java_pid|wc -l可以跑到4千以上都不会抛出too many open files。 
但是我们通过以上的文章详细介绍知道,这样也是治标不治本,找到java哪个文件不关闭文件描述符或者被请求过多的原因才是最重要的!
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值