我想用C++创建一个与“tail -f”相同功能的小代码:观察文本文件中的新行并在标准输出中显示它们。在C++中实现“tail -f”
的想法是有一个监视文件
有一个简单的办法做到这一点不开,每次关闭文件的主题?
我想用C++创建一个与“tail -f”相同功能的小代码:观察文本文件中的新行并在标准输出中显示它们。在C++中实现“tail -f”
的想法是有一个监视文件
有一个简单的办法做到这一点不开,每次关闭文件的主题?
只要继续阅读文件。如果读取失败,则不执行任何操作。没有必要反复打开和关闭它。但是,如果您的操作系统提供这些功能,您将发现使用特定于操作系统的功能来监视文件效率更高。
+1:尝试阅读到目前为止的文件末尾(对于合理长度的文件),每秒一次在实践中很便宜。你只是阅读,直到你完成,然后睡一秒,然后再次尝试阅读。 (如果你在Windows上,注意用正确的共享标志打开,这样你就不会锁定其他的作者,这可能意味着使用本地IO调用,而不是C++标准的调用...) – 2010-04-23 08:23:34
我在one of Perl manuals中读到这个,但它很容易翻译成标准C,而标准C又可以翻译成istream
s。
seek FILEHANDLE,POSITION,WHENCE
Sets FILEHANDLE's position, just like the "fseek" call of
"stdio".
<...>
A WHENCE of 1 ("SEEK_CUR") is useful for not moving the file
position:
seek(TEST,0,1);
This is also useful for applications emulating "tail -f". Once
you hit EOF on your read, and then sleep for a while, you might
have to stick in a seek() to reset things. The "seek" doesn't
change the current position, but it does clear the end-of-file
condition on the handle, so that the next "<FILE>" makes Perl
try again to read something. We hope.
至于我记得,fseek
被称为iostream::seekg
。所以你应该基本上做同样的事情:寻找文件的结尾,然后睡觉并用ios_base::cur
标志再次寻找以更新文件结束并读取更多数据。
代替sleep
ING,你可以(在从一个模拟的文件读取,实际上是块)正是使用的inotify,如the other answer建议,睡觉,直到该文件被更新/关闭。但这是Linux特有的,并不是标准的C++。
热爱“我们希望”关门。“这很奇怪,但它很好,因为它很奇怪”以及很多其他自我炫耀的实现,它们都是perl的典型代表... – 2010-04-23 09:17:37
@Stefano - 嗯,这里很好,因为它涉及到Perl的linewise实现文件阅读('
我也需要实现这一点,我只是写了一个标准C++的快速入门。黑客在文件中搜索最后一个0x0A(换行字符),并在最后一个换行值变为较大值时输出该换行之后的所有数据。该代码是在这里:
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int find_last_linefeed(ifstream &infile) {
infile.seekg(0,ios::end);
int filesize = infile.tellg();
for(int n=1;n<filesize;n++) {
infile.seekg(filesize-n-1,ios::beg);
char c;
infile.get(c);
if(c == 0x0A) return infile.tellg();
}
}
int main() {
int last_position=-1;
for(;;) {
ifstream infile("testfile");
int position = find_last_linefeed(infile);
if(position > last_position) {
infile.seekg(position,ios::beg);
string in;
infile >> in;
cout << in << endl;
}
last_position=position;
sleep(1);
}
}
相同https://stackoverflow.com/a/7514051/44729除了下面的代码使用,而不是GETC函数getline,而不是跳过新线
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
using namespace std;
static int last_position=0;
// read file untill new line
// save position
int find_new_text(ifstream &infile) {
infile.seekg(0,ios::end);
int filesize = infile.tellg();
// check if the new file started
if(filesize < last_position){
last_position=0;
}
// read file from last position untill new line is found
for(int n=last_position;n<filesize;n++) {
infile.seekg(last_position,ios::beg);
char test[256];
infile.getline(test, 256);
last_position = infile.tellg();
cout << "Char: " << test <<"Last position " << last_position<< endl;
// end of file
if(filesize == last_position){
return filesize;
}
}
return 0;
}
int main() {
for(;;) {
std::ifstream infile("filename");
int current_position = find_new_text(infile);
sleep(1);
}
}
文件大小
你可能也很难在纯C做这++ 。你将不得不使用一些平台特定的API。 (对于初学者,我不认为你可以用C++非独占地打开一个文件。) – sbi 2010-04-23 07:51:49
@sbi我不认为C++标准对排他性有什么要说的。 – 2010-04-23 07:54:08
有没有理由不能使用tail -f? – 2010-04-23 08:03:00