C++ 如何从不断更新的文件中读取和提取信息?
以下是我计划为项目构建实用程序的方式:C++ 如何从不断更新的文件中读取和提取信息?,c++,c,perl,shell,C++,C,Perl,Shell,以下是我计划为项目构建实用程序的方式: logdump将日志结果转储到文件log。如果文件已经存在,则结果将附加到现有结果(例如,如果每月创建一个新文件,则结果将附加到该月的同一文件) 提取读取日志结果文件,根据提供的参数提取相关结果 问题是我不想等待logdump完成写入log开始处理它。同样,我需要记住,直到我已经阅读了日志的地方,才能开始提取更多信息,这不是我想要做的 我需要实时结果,以便无论何时向日志结果文件添加内容,extract都将获得所需的结果 extract将执行的处理是通用的
- logdump将日志结果转储到文件log。如果文件已经存在,则结果将附加到现有结果(例如,如果每月创建一个新文件,则结果将附加到该月的同一文件)
- 提取读取日志结果文件,根据提供的参数提取相关结果
- 问题是我不想等待logdump完成写入log开始处理它。同样,我需要记住,直到我已经阅读了日志的地方,才能开始提取更多信息,这不是我想要做的
- 我需要实时结果,以便无论何时向日志结果文件添加内容,extract都将获得所需的结果
- extract将执行的处理是通用的(取决于它的一些命令行参数),但肯定是逐行执行的
<强>我如何使用C或C++或shell脚本或perl?< /强>
< p> <代码>尾-f/COD>将从文件读取并监视它在EOF到达时的更新,而不是直接退出。这是一种“实时”读取日志文件的简单方法。可以简单到:tail -f log.file | extract
或者
tail-n0-f
这样它只打印新行,而不是现有行。或者tail-n+0-f
显示整个文件,然后继续更新。用于此操作的传统unix工具是tail-f
,它会一直读取附加到其参数的数据,直到将其终止。所以你可以
tail -c +1 -f log | extract
在unix世界中,从连续附加到文件的数据中读取数据被称为“拖尾”。在Perl中,模块执行相同的任务
use File::Tail;
my $log_file = File::Tail->new("log");
while (defined (my $log_line = $log_file->read)) {
process_line($log_line);
}
使用
logdump的简单代理
#! /usr/bin/perl
use warnings;
use strict;
open my $fh, ">", "log" or die "$0: open: $!";
select $fh;
$| = 1; # disable buffering
for (1 .. 10) {
print $fh "message $_\n" or warn "$0: print: $!";
sleep rand 5;
}
以及下面的提取
框架,以获得所需的处理。当logfile
遇到文件结尾时,logfile.eof()
为true。调用logfile.clear()
#include <iostream>
#include <fstream>
#include <cerrno>
#include <cstring>
#include <unistd.h>
int main(int argc, char *argv[])
{
const char *path;
if (argc == 2) path = argv[1];
else if (argc == 1) path = "log";
else {
std::cerr << "Usage: " << argv[0] << " [ log-file ]\n";
return 1;
}
std::ifstream logfile(path);
std::string line;
next_line: while (std::getline(logfile, line))
std::cout << argv[0] << ": extracted [" << line << "]\n";
if (logfile.eof()) {
sleep(3);
logfile.clear();
goto next_line;
}
else {
std::cerr << argv[0] << ": " << path << ": " << std::strerror(errno) << '\n';
return 1;
}
return 0;
}
最后,如果你坚持自己做举重,有一个:
如何在perl中实现tail-f?
初试
seek(GWFILE, 0, 1);
语句seek(GWFILE,0,1)
不会更改当前位置,但会清除句柄上的文件结束条件,以便下一个
使Perl再次尝试读取某些内容
如果这不起作用(它依赖于stdio实现的特性),那么您需要类似这样的东西:
for (;;) {
for ($curpos = tell(GWFILE); <GWFILE>; $curpos = tell(GWFILE)) {
# search for some stuff and put it into files
}
# sleep for a while
seek(GWFILE, $curpos, 0); # seek to where we had been
}
(;;)的{
对于($curpos=tell(GWFILE);$curpos=tell(GWFILE)){
#搜索一些东西并将其放入文件中
}
#睡一会儿
寻找(GWFILE,$curpos,0)#寻找我们曾经去过的地方
}
如果这仍然不起作用,请查看中的clearr
方法,该方法重置句柄上的错误和文件结束状态
还有一个来自CPAN的模块
虽然这符合我的需要,有没有办法使用C或C++?@拉泽:你可以总是“欺骗”,并查看“黑客的满葩格”-源代码尾。IIRC,它是非常简单的C代码。看这里:在这些情况下,我尝试修改日志以转到数据库。那么你就很容易得到你还没有处理过的记录了。如果您还没有设计日志部分,那么这可能是一个不错的选择。
seek(GWFILE, 0, 1);
for (;;) {
for ($curpos = tell(GWFILE); <GWFILE>; $curpos = tell(GWFILE)) {
# search for some stuff and put it into files
}
# sleep for a while
seek(GWFILE, $curpos, 0); # seek to where we had been
}