Форум программистов, компьютерный форум CyberForum.ru

Как регулярно считывать последнюю строку в файле - C++

Восстановить пароль Регистрация
 
florgas
 Аватар для florgas
5 / 4 / 0
Регистрация: 28.09.2010
Сообщений: 339
30.10.2013, 22:44     Как регулярно считывать последнюю строку в файле #1
Добрый день. Имеется текстовый файл. Он постоянно обновляется и в его конец дописываются строки. Необходимо считывать новую строку непосредственно в string, как только она появляется в файле. Вот и вопрос: как это реализовать? Считывать все по порядку до последней строки - не самая лучшая идея, ибо файл может быть большим и это не самый оптимальный вариант. А вот как сразу считать последнюю строку. И тут же вопрос, как отловить добавление новых строк в файл? У меня мысли разве что взять последнюю строку и постоянно ее сравнивать с последней. Если они станут различными, значит была добавлена новая строка в файл. Надеюсь вопрос понятен. Спасибо.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
30.10.2013, 22:44     Как регулярно считывать последнюю строку в файле
Посмотрите здесь:

Как перейти на новую строку в файле C++
Не хочет считывать второй раз строку C++
Как считывать большую строку по частям? C++
Как считывать строку с пробелами? C++
C++ Как заменить в файле строку, используя std::map?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
DiffEreD
 Аватар для DiffEreD
1420 / 757 / 95
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
31.10.2013, 01:54     Как регулярно считывать последнюю строку в файле #2
Могу предложить такое решение (с использованием boost):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include <iostream>
#include <iterator>
#include <fstream>
#include <vector>
#include <string>
#include <algorithm>
#include <thread>
#include <chrono>
#include <cstdlib>
#include <conio.h>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/algorithm/string.hpp>
#include <windows.h>
 
namespace fs = boost::filesystem;
using input = std::istreambuf_iterator<char>;
 
int main()
{
   SetConsoleCP (1251); SetConsoleOutputCP (1251);
 
   fs::path path("D:/file.txt");
   if(!fs::is_regular_file(path))
   {
      std::cout << "Файла не существует или неверно задано его имя!" << std::endl;
      return EXIT_FAILURE;
   }
 
   std::ifstream ifs(path.string());
   if(!ifs.is_open())
   {
      std::cout << "Не удалось открыть файл для чтения!" << std::endl;
      return EXIT_FAILURE;
   }
 
   auto last_modified = fs::last_write_time(path);
 
   std::vector<std::string> lines;
   std::string text{input(ifs), input()};
   auto pos = ifs.tellg();
   ifs.close();
 
   boost::split(lines, text, boost::is_any_of("\n"), boost::token_compress_on);
   for(std::string& s : lines) std::cout << s << std::endl;
 
   std::vector<std::string> new_lines;
 
   while(true)
   {
      //ждем 5 секунд и проверяем не изменился ли файл:
      std::this_thread::sleep_for(std::chrono::seconds(5));
      if(last_modified != fs::last_write_time(path))
      {
         last_modified = fs::last_write_time(path);
         std::cout << "\n***** Файл был изменен. *****\n" << std::endl;
         ifs.open(path.string());
         ifs.seekg(pos);
         text.assign((input(ifs)), input()).erase(0, 1); //erase удаляет первый '\n'
         pos = ifs.tellg();
         ifs.close();
         std::cout << text << std::endl;
         boost::split(new_lines, text, boost::is_any_of("\n"), boost::token_compress_on);
 
         std::copy(new_lines.begin(), new_lines.end(), std::back_inserter(lines));
      }
      if(kbhit())
         break;
   }
 
   std::cout << "\n\n\n***** Все строки: *****" << std::endl;
   for(std::string& s : lines) std::cout << s << std::endl;
 
   return 0;
}
Alex5
881 / 616 / 81
Регистрация: 12.04.2010
Сообщений: 1,551
31.10.2013, 13:12     Как регулярно считывать последнюю строку в файле #3
Цитата Сообщение от florgas Посмотреть сообщение
как отловить добавление новых строк в файл?
В качестве критерия можно использовать размер файла. Запомним sz - размер файла. Если размер увеличился, значит, начиная с позиции sz записана новая строка( или несколько новых строк). Для перемещения указателя на позицию sz можно использовать функцию fstream::seekg().
florgas
 Аватар для florgas
5 / 4 / 0
Регистрация: 28.09.2010
Сообщений: 339
01.11.2013, 21:42  [ТС]     Как регулярно считывать последнюю строку в файле #4
Цитата Сообщение от DiffEreD Посмотреть сообщение
Могу предложить такое решение (с использованием boost):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include <iostream>
#include <iterator>
#include <fstream>
#include <vector>
#include <string>
#include <algorithm>
#include <thread>
#include <chrono>
#include <cstdlib>
#include <conio.h>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/algorithm/string.hpp>
#include <windows.h>
 
namespace fs = boost::filesystem;
using input = std::istreambuf_iterator<char>;
 
int main()
{
   SetConsoleCP (1251); SetConsoleOutputCP (1251);
 
   fs::path path("D:/file.txt");
   if(!fs::is_regular_file(path))
   {
      std::cout << "Файла не существует или неверно задано его имя!" << std::endl;
      return EXIT_FAILURE;
   }
 
   std::ifstream ifs(path.string());
   if(!ifs.is_open())
   {
      std::cout << "Не удалось открыть файл для чтения!" << std::endl;
      return EXIT_FAILURE;
   }
 
   auto last_modified = fs::last_write_time(path);
 
   std::vector<std::string> lines;
   std::string text{input(ifs), input()};
   auto pos = ifs.tellg();
   ifs.close();
 
   boost::split(lines, text, boost::is_any_of("\n"), boost::token_compress_on);
   for(std::string& s : lines) std::cout << s << std::endl;
 
   std::vector<std::string> new_lines;
 
   while(true)
   {
      //ждем 5 секунд и проверяем не изменился ли файл:
      std::this_thread::sleep_for(std::chrono::seconds(5));
      if(last_modified != fs::last_write_time(path))
      {
         last_modified = fs::last_write_time(path);
         std::cout << "\n***** Файл был изменен. *****\n" << std::endl;
         ifs.open(path.string());
         ifs.seekg(pos);
         text.assign((input(ifs)), input()).erase(0, 1); //erase удаляет первый '\n'
         pos = ifs.tellg();
         ifs.close();
         std::cout << text << std::endl;
         boost::split(new_lines, text, boost::is_any_of("\n"), boost::token_compress_on);
 
         std::copy(new_lines.begin(), new_lines.end(), std::back_inserter(lines));
      }
      if(kbhit())
         break;
   }
 
   std::cout << "\n\n\n***** Все строки: *****" << std::endl;
   for(std::string& s : lines) std::cout << s << std::endl;
 
   return 0;
}
Это все хорошо, но слишком сложно. Можно проще: считывать постоянно последнюю строку в файле и проверять ее с последней строкой в файле, которая была записана ранее в отдельную строку. Если строка изменила, т.е. стала не равна, то файл изменился.
Вопрос лишь в том, как прочитать конкретно последнюю строку?
Yandex
Объявления
01.11.2013, 21:42     Как регулярно считывать последнюю строку в файле
Ответ Создать тему
Опции темы

Текущее время: 06:12. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru