Как читать растущий текстовый файл на C ++?

Я пытаюсь читать из файла, который растет (что-то похожее на то, что 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); } в 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 я пытаюсь сохранить текущую конечную позицию файла, так что, когда я его снова открою, я могу пойти туда и прочитать, что было добавлено.

Я хотел бы знать, что не так в моем коде, и если действительно необходимо закрыть и снова открыть тот же файл для этой цели.

Спасибо.

Цикл неверен, как когда встречается tellg() возвращает -1 и нет проверки для eof() сразу после вызова getline() который должен быть. Изменить цикл:

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

Кроме того, поскольку p объявляется как size_t когда tellg() возвращает -1 значение p было установлено 4294967295 . Это означало, что seekg() был установлен за пределами файла. Измените тип p на std::streamoff и подтвердите, что вызов seekg() был успешным:

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

если действительно необходимо закрыть и снова открыть тот же файл для этой цели.

Нет, это не обязательно, но вам нужно clear() состояние eof из streamа. Ниже приведена альтернатива исправленной версии опубликованного кода:

 #include  #include  #include  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; } 

Этот метод верно работал для меня:

 #include  #include  #include  #include  #include  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; } } в #include  #include  #include  #include  #include  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; } } 

Этот код работает для меня:

 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); } } в 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); } } 
  • Ведение журнала исключений для служб WCF с использованием ELMAH
  • Logcat не отображает мои логические вызовы
  • Каталины. Прокачка с Tomcat 6.0
  • Пользовательский обработчик java.util.logging в tomcat
  • Регистрация SQL-запросов в android
  • Давайте будем гением компьютера.