linux下c/c++实例之二日志记录及文件读取

一、简介

      Linux下封装一些函数将需要的日志信息打印到控制台或写入文件,并读取文件。

二、详解

1、日志记录

(1)代码writelog.cpp

/*日志记录*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <assert.h>
#include <string.h>
#include <string>
#include <fcntl.h>
#include <stdarg.h>

enum switch_mode
{
    mode_minute,
    mode_hour,
    mode_day,
    mode_month
};
int file_fd = -1;
int log_file(switch_mode mode = mode_day)
{
    char file_path[512] = {0};
    char filetime[32] = {0};
    struct tm tm_time;
    time_t t_log;
    std::string log_time = "";

    assert(getcwd(file_path, 512) != NULL);    //当前目录
    if (file_path[strlen(file_path) - 1] != '/') {
        file_path[strlen(file_path)] = '/';
    }
    if(access(file_path, F_OK) != 0) {     //目录不存在
        std::string build_path ="mkdir -p ";
        build_path += file_path;
        assert(system(build_path.c_str()) !=0 );
    }

    t_log = time(NULL);
    localtime_r(&t_log, &tm_time);
    strftime(filetime, sizeof(filetime), "%Y%m%d%H%M%S", &tm_time); //日志的时间
    switch(mode) {  //日志存储模式
    case mode_minute:
        log_time.assign(filetime, 0, 12);
        break;
    case mode_hour:
        log_time.assign(filetime, 0, 10);
        break;
    case mode_day:
        log_time.assign(filetime, 0, 8);
        break;
    case mode_month:
        log_time.assign(filetime, 0, 6);
        break;
    default:
        log_time.assign(filetime, 0, 8);
    }
    strcat(file_path, "log_");
    strcat(file_path, log_time.c_str());
    strcat(file_path, ".log");

    file_fd = open(file_path, O_RDWR|O_CREAT|O_APPEND, 0666);
    assert(file_fd != -1);
    return 0;
}
void write_cmd(const char *fmt,...)
{
    va_list ap;
    va_start(ap,fmt);
    vprintf(fmt,ap);
    va_end(ap);
}
int write_log(const char *msg, ...)
{
    char final[2048] = {0};   //当前时间记录
    va_list vl_list;
    va_start(vl_list, msg);
    char content[1024] = {0};
    vsprintf(content, msg, vl_list);   //格式化处理msg到字符串
    va_end(vl_list);

    time_t  time_write;
    struct tm tm_Log;
    time_write = time(NULL);        //日志存储时间
    localtime_r(&time_write, &tm_Log);
    strftime(final, sizeof(final), "[%Y-%m-%d %H:%M:%S] ", &tm_Log);

    strncat(final, content, strlen(content));
    assert(msg != NULL && file_fd != -1);
    assert( write(file_fd, final, strlen(final)) == strlen(final));
    return 0;
}
void close_file()
{
    close(file_fd);
}
/******************日志记录测试******************/
int main()
{
    log_file();
    write_cmd("the address for cmd:%d\n", 100);
    write_log("the address for log:%d\n", 200);
    close_file();
    return 0;
}

(2)编译运行

g++ -o writelog writelog.cpp
运行控制台显示:

文件log_20151105.log内容:

2、文件读取

(1)代码readdata.c
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
int read_file(char *file_name)
{
    char *buff;
    FILE *fp = fopen(file_name, "r+");
    assert(fp);
    int flag = fseek(fp, 0, SEEK_END);
    assert(flag == 0);
    int len = ftell(fp);
    buff = (char *)malloc(sizeof(char) * (len + 1));
    flag = fseek(fp, 0, SEEK_SET);
    assert(flag == 0);

    int num = fread(buff, 1, len + 1, fp);
    assert(num == len);

    printf("len:%d, num:%d, buff:%s", len, num, buff);
    free(buff);
    buff = NULL;
    fclose(fp);
    return 0;
}
int read_file_p(char *file_name)
{
    char buff[1024] = {0};
    FILE *fp = fopen(file_name, "r+");
    assert(fp);
    int ch;
    int i = 0;
    do {
        ch = fgetc(fp);
        buff[i++] = ch;
    } while(ch != EOF);
    buff[i - 2] = '\0';
    fclose(fp);

    printf("buff:%s\n", buff);
    return 0;
}
int main(int argc, char *argv[])
{
    assert(argc == 2);
    read_file(argv[1]);
    read_file_p(argv[1]);
    return 0;
}
(2)编译运行
gcc -o readdata readdata.c
./readdata log_20151105.log

三、总结

(1)上述写日志的代码对于较长的日志会导致段错误,需要修改代码。当然也可以参考Qt或C++式的日志,可以记录无限长的日志。
(2)读取日志中采用了两种不同方式,建议采用第一种动态分配内存大小,第二种对于大文件会导致段错误。

(3)若有建议,请留言,在此先感谢!

你可能感兴趣的:(c,linux)