日期:2014-05-16  浏览次数:20822 次

请问怎样正确截短日志文件?
我在linux下写了段记录日志的代码,想再加个方法,保留一定行数,去掉历史数据.
但后来发现判断行数可能会复杂,所以就变通一下用文件大小作判断.
我有两个问题:
1.这个方法执行以后没有按照我要保留的文件长度来工作,我不知道用fseek定位,再fgets文件后面的字串的方法有没有问题.
2.有没有简单快速的方法实现按行数去掉历史数据的?
谢谢!

代码如下:
//检查日志文件行数,如果超过规定的最大长度则截取最新的日志行数,去掉旧的行.
void   ShrunkFile(char   *FileName,long   Size)
{
        FILE   *pFile;
        long   file_size=0,lPos=0;
        char   *Buffer;
        int   letter;

        if   (Size <=0)   return   ;

        if   (!(pFile   =   fopen(FileName, "r ")))
                return;
        //移动到文件尾
        fseek(pFile,0,SEEK_END);
        //得到文件长度
        file_size   =   ftell(pFile);
        printf( "filesize:%d\n ",file_size);
        lPos=file_size-Size;
        if   (lPos <=0)
                return;
        //从文件首移动到要截取的位置
        fseek(pFile,lPos,SEEK_SET);
        //找到第一个回车符,确定下一行的首位
        while   ((letter   =   fgetc(pFile)),letter!=EOF&&letter!= '\n ')
        {
                lPos++;
                printf( "%c ",letter);
        }
        lPos++;
        fseek(pFile,lPos,SEEK_SET);
        //分配缓冲区
        Buffer   =   (char   *)   malloc(Size);
        if   (Buffer   !=   NULL)
        {
                fgets(Buffer,Size,pFile);
                fclose(pFile);
                //printf(Buffer);
                if   (pFile=fopen(FileName, "w "))
                        fputs(Buffer,pFile);

        }
        free(   Buffer);
        fclose(pFile);

        return   ;
}

------解决方案--------------------
直接有效的方法就是每天写一个文件,
如果楼主不愿这么做,“另建一个临时文件,从日志文件里读出来后再覆盖掉旧文件”是不错的选择,从速度上来说,这比楼主正在尝试的方法要快,而且简单,用命令tail就可完成了。
------解决方案--------------------
有一个工具是专门完成这样工作的
logrotate,它可以按天,周,月等对日志进行卷写,也可以按大小卷写。