c++实现tailf命令

lnkTail.h

/***********************************************************
 * 文件名称:    lnkTail.h
 * 功能描述:    类似linux系统tailf命令的功能
 * 实现原理:    每次比较文件大小,发生变化则打开文件偏移到
 *               上一次记录的文件大小处再读取文件内容
 * 主要实现:    另起线程将每次读取的内容存入队列,供其它调
 *               用模块实时监控日志。
 * 历史信息:    lnk 创建 2015.10.25
 ************************************************************/
#ifndef _LNK_TAIL_H_
#define _LNK_TAIL_H_

#include <string>
#include <queue>

using namespace std;

typedef struct tag_Line{
    string sText;   //行内容
    string sTime;   //读取时的时间
}Line;

class Tail{
public:
    void SetFileName(string sPramFileName); //设置要tailf的文件名称
    string GetFileName();                   //获取文件名称
    void TailFile();                        //tailf文件
    Line GetLine();                         //获取行
    bool Empty();                           //判断是否有新行加入队列
private:
    string sFileName;                       //文件名称
    queue<Line> qLines;                     //行队列
};

#endif //_LNK_TAIL_H_


lnkTail.cpp

/***********************************************************
 * 文件名称:    lnkTail.cpp
 * 功能描述:    类似linux系统tailf命令的功能的实现
 * 历史信息:    lnk 创建 2015.10.25
 ************************************************************/
#include <stdio.h>  
#include <stdlib.h>  
#include <unistd.h>  
#include <malloc.h>  
#include <sys/stat.h>  
#include <time.h>
#include <pthread.h>
#include <string.h>

#include "lnkTail.h"

#define _(s) s  

//tailf线程参数结构
typedef struct tag_TailPram{
    char *pcFileName;
    queue<Line> *pqLines;
}TailPram;

//函数功能:获取文件大小
//参数说明:const char * [IN] 文件名称
//返 回 值:size_t 文件大小
//历史信息:lnk 创建 2015.10.25
static size_t filesize(const char *filename)  
{  
    struct stat sb;  
  
    if (!stat(filename, &sb)) return sb.st_size;  
    return 0;  
} 

//函数功能:设置文件名称
//参数说明:string [IN] 文件名称
//返 回 值:无
//历史信息:lnk 创建 2015.10.25
void Tail::SetFileName(string sPramFileName)
{
    this->sFileName = sPramFileName;
}

//函数功能:获取文件名称
//参数说明:无
//返 回 值:string 文件名称
//历史信息:lnk 创建 2015.10.25
string Tail::GetFileName()
{
    return this->sFileName;
}

//函数功能:获取文件名称
//参数说明:TailPram * 线程参数
//返 回 值:-1失败 0线程结束
//历史信息:lnk 创建 2015.10.25
void* TailFileToQueue(void *ptr)
{
    char cBuf[BUFSIZ];  
    size_t osize, nsize; 
    FILE *pf;
    int nCnt = 0;
    TailPram *fileAndQue = (TailPram *)ptr;
    for (osize = filesize(fileAndQue->pcFileName);;)
    {  
        nsize = filesize(fileAndQue->pcFileName);  
        if (nsize != osize) {  
            if (!(pf = fopen(fileAndQue->pcFileName, "r"))) {  
                fprintf(stderr, _("Cannot open \"%s\" for read\n"), fileAndQue->pcFileName);  
                return (void *)-1;
            }  
            if (!fseek(pf, osize, SEEK_SET))
            {
                while ((nCnt = fread(cBuf, 1, sizeof(cBuf), pf)) > 0)  
                {
                    //fwrite(cBuf, 1, nCnt, stdout);  
                    time_t lt;
                    Line stNewLine;
                    stNewLine.sText = cBuf;
                    lt = time(NULL);
                    stNewLine.sTime = ctime(<); 
                    fileAndQue->pqLines->push(stNewLine);
                    //printf("%s %s",stNewLine.sText.c_str(), stNewLine.sTime.c_str());
                }
            }
        //fflush(stdout);  
        fclose(pf);  
        osize = nsize;  
    }  
    usleep(250000);  
    }
    
    return (void*)0;
}

//函数功能:tail文件
//参数说明:无
//返 回 值:无
//历史信息:lnk 创建 2015.10.25
void Tail::TailFile()
{
    pthread_t pid;
    TailPram *fileAndQue = new TailPram;
    fileAndQue->pcFileName = (char *)malloc(strlen(this->sFileName.c_str()));
    strcpy(fileAndQue->pcFileName, this->sFileName.c_str());
    fileAndQue->pqLines = &this->qLines;
    int ret = pthread_create(&pid, NULL, TailFileToQueue, (void*)fileAndQue);
    if(ret)
    {
        fprintf(stderr, _("Cannot create pthread!\n"));
        return;
    }
    //pthread_join(pid, NULL);
    //fprintf(stderr, _("tail stop"));
}

//函数功能:是否监控到新行
//参数说明:无
//返 回 值:true false
//历史信息:lnk 创建 2015.10.25
bool Tail::Empty()
{
    return this->qLines.empty();
}

//函数功能:获取行
//参数说明:无
//返 回 值:Line
//历史信息:lnk 创建 2015.10.25
Line Tail::GetLine()
{
    Line lRes;
    if(!this->qLines.empty())
    {
        lRes = this->qLines.front();
        this->qLines.pop();
    }
    
    return lRes;
}


mian.cpp  主要写写怎么使用!

#include <iostream>
#include <stdlib.h> 

#include "lnkTail.h"

int main(int argc, char **argv)
{
	Tail myTail;
    
    if(argc != 2)
    {
        cout<<"use like tail filename!"<<endl;
        return -1;
    }
    
    myTail.SetFileName(argv[1]);    //tailf文件名由参数传入
    myTail.TailFile();              //启动tailf线程
    while(1)                        //循环获取监控的新行
    {
        if(!myTail.Empty())
        {
            Line tmp = myTail.GetLine();
            cout<<tmp.sText<<tmp.sTime;
        }
        else
        {
            usleep(250000);
        }
    }
    
	return 0;
}

当然还需要在合适的地方把内存给释放了,懒得改了。有时间再看下。。


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值