我正在尝试读取一个正在增长的文件(类似于 tail -F
所做的),但我的代码肯定存在一些问题:
string log, logFile("test.log");
size_t p = 0;
while(true)
{
ifstream ifs(logFile.c_str());
ifs.seekg(p); //*1
while(ifs.eof() == false)
{
getline(ifs, log);
cout << log << endl;
p = ifs.tellg(); //*2
}
nanosleep(&pause, NULL);
}
如果没有//*1 和//*2 行,日志文件会被正确读取到末尾,但如果添加新行,则不会发生任何事情。
通过 seekg 和 tellg,我试图存储文件的当前结束位置,这样当我重新打开它时,我可以直接到那里并读取已添加的内容。
我想知道我的代码有什么问题,以及是否真的有必要为此关闭并重新打开同一个文件。
谢谢。
最佳答案
遇到 eof()
时循环不正确 tellg()
返回 -1
并且在调用 getline()
之后没有立即检查 eof()
,而这是需要的。将循环更改为:
while (getline(ifs, log))
{
cout << log << endl;
p = ifs.tellg();
}
此外,当 tellg()
返回 -1
的值时,p
被声明为 size_t
p
被设置为 4294967295
。这意味着 seekg()
被设置为超出文件末尾。将 p
的类型更改为 std::streamoff
并确认对 seekg()
的调用成功:
if (ifs.seekg(p))
{
while (getline(ifs, log))
{
cout << log << endl;
p = ifs.tellg();
}
}
if it is really necessary to close and reopen the same file for this purpose.
不,这不是必需的,但您需要从流中clear()
eof
状态。以下是已发布代码的更正版本的替代方法:
#include <iostream>
#include <string>
#include <fstream>
int main()
{
std::ifstream ifs("test.log");
if (ifs.is_open())
{
std::string line;
while (true)
{
while (std::getline(ifs, line)) std::cout << line << "\n";
if (!ifs.eof()) break; // Ensure end of read was EOF.
ifs.clear();
// You may want a sleep in here to avoid
// being a CPU hog.
}
}
return 0;
}
关于c++ - 如何在 C++ 中读取不断增长的文本文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11757304/