您的位置:首页 > 运维架构 > Linux

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

2015-11-05 10:16 615 查看


一、简介

      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