-->

如何阅读在C ++越来越文本文件?(How to read a growing text file

2019-06-17 14:53发布

我试图从增长(类似于东西读取文件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我想存储文件的当前终点位置,所以,当我重新打开它,我可以去那里海峡和读取已添加了什么。

我想知道什么是错在我的代码,如果确有必要关闭并重新打开同一个文件用于这一目的。

谢谢。

Answer 1:

循环是不正确时为eof()遇到tellg()返回-1 ,并没有检查的eof()调用后立即getline()这需要有。 改变的环路到:

while (getline(ifs, log))
{
    cout << log << endl;
    p = ifs.tellg();
}

另外,如p被声明为size_ttellg()返回-1的值p被设定为4294967295 。 这意味着seekg()被设定为超出了文件的末尾。 改变的类型pstd::streamoff并确认调用seekg()是成功的:

if (ifs.seekg(p))
{
    while (getline(ifs, log))
    {
        cout << log << endl;
        p = ifs.tellg();
    }
}

如果确有必要关闭并重新打开同一个文件用于这一目的。

不,这是没有必要的,但你需要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;
}


Answer 2:

这种方法忠实地为我工作:

#include <string>
#include <chrono>
#include <thread>
#include <fstream>
#include <iostream>

int main(int, char* argv[])
{
    // open file passed in on command line (at end of file)
    std::ifstream ifs(argv[1], std::ios::ate);

    if(!ifs.is_open())
    {
        std::cerr << "ERROR: opening log file: " << argv[1] << '\n';
        return 1;
    }

    // remember file position
    std::ios::streampos gpos = ifs.tellg();

    std::string line;
    bool done = false;

    while(!done)
    {
        // try to read line
        if(!std::getline(ifs, line) || ifs.eof())
        {
            // if we fail, clear stream, return to beginning of line
            ifs.clear();
            ifs.seekg(gpos);

            // and wait to try again
            std::this_thread::sleep_for(std::chrono::milliseconds(100));
            continue;
        }

        // remember the position of the next line in case
        // the next read fails
        gpos = ifs.tellg();

        // process line here
        std::cout << "line: " << line << std::endl;
    }
}


Answer 3:

此代码的工作对我来说:

struct timespec pause;
pause.tv_sec  = 1;
pause.tv_nsec = 0;

std::ifstream ifs("test.log");
std::streamoff p;

if(ifs.is_open())
{
    std::string line;

    while(true)
    {
        if(ifs.seekg(p))
        {
            while(std::getline(ifs, line))
            {
                std::cout << line << std::endl;
                p = ifs.tellg();
            }
        }

        ifs.clear();

        nanosleep(&pause, NULL);
    }
}


文章来源: How to read a growing text file in C++?