小程序开发平台网站推荐,免费logo设计 u钙,全国好的深圳网站设计,wordpress 性能调优公司的asterisk系统已经发生了两次crash#xff0c;检查日志#xff0c;都是在日志文件写满到2G后自动执行转储时#xff0c;日志还在写继续写入而导致的。google以后#xff0c;发现了下面这边文章#xff0c;赞#xff01;解决了文件大小限于2G的问题#xff0c;转帖到…公司的asterisk系统已经发生了两次crash检查日志都是在日志文件写满到2G后自动执行转储时日志还在写继续写入而导致的。google以后发现了下面这边文章赞解决了文件大小限于2G的问题转帖到自己的空间保留。突破Linux上面ftell函数2GB的文件大小限制 http://www.demix.cn/h?z28507
在 32 位元的 Linux 上面写超过 2GB 的档案会发生错误甚至导致程式终止执行。这是因为 Linux 的系统内部处理档案时用的指标定义为 long而 long 在 32 位元的系统上的大小为 32 位元因此最大只能支援 2^31-1 2,147,483,647 bytes 等於是 2GB 扣掉 1 byte 的档案大小64 位元的系统 (例如 AMD64 或 IA64) 则因为 long 定义成 64 位元所以不会有问题..# if __WORDSIZE 64typedef long int int64_t;# endif不过在 FreeBSD 上面即使是 32 位元的系统也不会有 2GB 档案大小的限制这是因为 FreeBSD 内部处理档案时本来就是使用 64 位元的数字当作指标所以不会有问题因此在 32 位元的 Linux 上面程式需要作一些额外处理才能正确写超过 2GB 的档案我们先写一个小程式来测试一下 (large.c)#include stdio.h#include string.h#include stdlib.h#include fcntl.h#include sys/types.h#include sys/stat.h#include signal.h#include unistd.h#include errno.hvoid sig_xfsz(int sig){printf(ERROR: SIGXFSZ (%d) signal received!\n, sig);}int main(){int i, fd;char dummy[4096];signal( SIGXFSZ, sig_xfsz );unlink(large.log);fd open(large.log, O_CREAT|O_WRONLY, 0644 );bzero( dummy, 4096 );/* 2GB 4KB x 524288 */for( i 0 ; i 524287 ; i )write( fd, dummy, 4096 );write( fd, dummy, 4095 );printf(large.log: 2147483647 bytes\n);if( write( fd, dummy, 1 ) 0 )printf(ERROR: %s [errno:%d]\n,strerror(errno),errno);elseprintf(large.log: 2147483648 bytes\n);close(fd);exit(0);}在 32 位元的 Linux 下面以上程式编译后若没有特殊处理执行结果如下:# gcc -o large32 large.c# ./large32large.log: 2147483647 bytesERROR: SIGXFSZ (25) signal received!ERROR: File too large [errno:27]在写第 2147483648 byte 的时候程式会收到 signal SIGXFSZ同时 write() 会回传 -1 错误errno 则为 27 (File too large)。更甚者如果程式没有像上面一样去处理 SIGXFSZ 的话内定的 signal handler 甚至会造成程式停止执行并产生 core dump接下来我们在编译同一个程式的时候加入 -D_FILE_OFFSET_BITS64 再试看看:# gcc -D_FILE_OFFSET_BITS64 -o large64 large.c# ./large64large.log: 2147483647 byteslarge.log: 2147483648 bytes果然顺利突破 2GB 的限制了!而同样的程式在 32 位元的 FreeBSD 下面不论有没有加这个定义跑起来都是正确的不过处理这些大档案的时候除了编译程式时的参数不同外有些函数的使用上也要作一些调整例如 fseek() 与 ftell() 这两个原本使用到 long integer 当作 offset 的函数:int fseek(FILE *stream, long offset, int whence);long ftell(FILE *stream);只要系统是 32 位元即使是在 FreeBSD 下面都需要改为使用 off_t 的版本:int fseeko(FILE *stream, off_t offset, int whence);off_t ftello(FILE *stream);在 Linux 下面如果 _FILE_OFFSET_BITS 定义为 64则 off_t 这个型态会自动转成 64 位元的大小在 FreeBSD 上面off_t 本来就是 64 位元的大小)每种系统支援大於 2GB 的档案读写所需要的编译选项都会有一些差异即使是同样是 Linux 也会因为 32 位元或 64 位元而有不同。有一个简单的方法可以判断就是利用 glibc 提供的 getconf 来取得编译(compile)以及连结(linking)时所需的参数:# getconf LFS_CFLAGS-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS64# getconf LFS_LDFLAGS #上面是在 32 位元的 Redhat Linux 上面跑出来的结果代表的是在这个系统上若要让程式支援 2GB 的档案读写编译(compile)时需要加上 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS64 这两个参数连结(linking)时则不用加任何参数