Мне нужен журнал событий кольцевой для qt5 c++. С функцией чтения и записи строк из файла. Размер файла на 128 строк. Количество символов в строке ограничен 128 символов. Выравнивания строк не нужно на 128 символов пробелами или еще чем. Если больше 128 символов в строке то просто обрезаем. Компьютер может отключатся от сети поэтому нужно хранить голову в файле во избежание потери куда писать новую строку. Пишем и читаем по кругу.
Написал код, но проблема возникает с индексом при чтение. Если записать 128 строк, то сначала прочитает «Сообщение 0» а потом «Сообщение 127» понятно, что должно прочитаться «Сообщение 127» …. «Сообщение 0» а тут наоборот. Чет не могу найти ошибку с индексом.
#include "mainwindow.h"
#include <QFile>
#include <QTextStream>
#include <QDebug>
#include <QStringList>
#include <QApplication>
class RingBufferLog {
public:
RingBufferLog(const QString &filename) : m_filename(filename) {
// Инициализация файла, если его нет
if (!QFile::exists(m_filename)) {
QFile file(m_filename);
if (file.open(QIODevice::WriteOnly)) {
QTextStream out(&file);
// Записываем начальные значения головы и хвоста (первые 2 строки)
out << "0\n"; // head
out << "0\n"; // tail
// Заполняем остальные строки пустыми значениями
for (int i = 2; i < 130; ++i) {
out << "\n";
}
file.close();
}
}
// Читаем текущие head и tail
readPointers();
}
// Добавление строки в лог (FIFO)
bool write(const QString &message) {
QFile file(m_filename);
if (!file.open(QIODevice::ReadWrite)) {
qWarning() << "Cannot open file for writing:" << m_filename;
return false;
}
QTextStream in(&file);
QStringList lines;
while (!in.atEnd()) {
lines << in.readLine();
}
// Обрезаем строку, если она длиннее 128 символов
QString truncatedMsg = message.left(128);
// Обновляем head (новая позиция для записи)
int newHead = (m_head + 1) % 128;
m_tail = (m_tail + 1) % 1048576;
// Записываем строку в новую позицию
//lines[newHead + 2] = truncatedMsg; // +2 потому что первые 2 строки - head и tail
lines[m_head + 2] = truncatedMsg; // +2 потому что первые 2 строки - head и tail
// Обновляем head в файле
lines[0] = QString::number(newHead);
lines[1] = QString::number(m_tail);
// Перезаписываем файл
file.resize(0); // Очищаем файл
QTextStream out(&file);
for (const QString &line : lines) {
out << line << "\n";
}
m_head = newHead;
file.close();
return true;
}
// Чтение всех строк в порядке FIFO
QStringList readAll() {
QStringList messages;
QFile file(m_filename);
if (!file.open(QIODevice::ReadOnly)) {
qWarning() << "Cannot open file for reading:" << m_filename;
return messages;
}
QTextStream in(&file);
QStringList lines;
while (!in.atEnd()) {
lines << in.readLine();
}
file.close();
if (lines.size() < 130) {
qWarning() << "File is corrupted";
return messages;
}
int curent = m_tail < 128 ? m_tail : 128;
//int current = m_head;
int current = m_tail ;
qDebug() << "m_tail" << m_tail << "m_head" << m_head << "curent" << curent;
for (int i = 0; i < curent; i++)
{
messages << lines[((current - i) % 128) + 2];
// qDebug() << "точки массива" << ((current - i) % 128) << "i" << i << "current" << current;
}
// qDebug() << current << m_head << "messages" << messages << messages.size() << "\n";
return messages;
}
private:
QString m_filename;
int m_head = 0;
int m_tail = 0;
void readPointers() {
QFile file(m_filename);
if (!file.open(QIODevice::ReadOnly)) {
qWarning() << "Cannot open file for reading pointers:" << m_filename;
return;
}
QTextStream in(&file);
QString headLine = in.readLine();
QString tailLine = in.readLine();
m_head = headLine.toInt();
m_tail = tailLine.toInt();
file.close();
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
system("rm event_log.txt");
RingBufferLog log("event_log.txt");
// Запись в лог
//log.write("Event 1: System started");
//log.write("Event 2: User logged in");
//log.write("Event 3: Data processed");
// Записываем 145 сообщений
for (int i = 0; i < 128; ++i) {
log.write("Сообщение " + QString::number(i));
}
// Читаем обратно
QStringList events = log.readAll();
qDebug() << "Всего сообщений:" << events.size();
for (const QString &event : events) {
qDebug() << event;
}
// MainWindow w;
// w.show();
return a.exec();
}
Перемещено Dimez из general