Отслеживание изменений в файле и его вывод в мэмо

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Отслеживание изменений в файле и его вывод в мэмо

Сообщение lich100 » 08.11.2010 14:36:28

Всем привет. Нужна помощь с программой. Она уже работает, но нужно ее немного подкрутить, но я пока не могу понять как это сделать.
Программа создана для запуска, администрирования и управления серверами игры Urban Terror. Нужна помощь доделать одну из ее функций, а именно перехват данных из консоли игры. В общем она по нажатию кнопки копирует лог файл чужой программы, ассоциирует его, открывает на чтение, в цикле считывает его и выводит в мэмо. Выводит она его естесственно каждый раз заново, а мне нужно чтобы выводились только изменения в файле. То есть проверка на изменение прошла и только тогда изменение выводится в мэмо. Как можно это реализовать? OC Windows Seven, но вообще будет кросс платформенная, использую правильные компоненты вроде.
Вот мой нынешний код для этой кнопки:

Код: Выделить всё
procedure TForm1.Button18Click(Sender: TObject);
var
  log: string;
begin
  log:= ' ';
  Form1.Memo1.Clear;
  if FileExists(APath + 'qconsole.log') then DeleteFile(Pchar(APath + 'qconsole.log'));
  CopyFile(Pchar(UrtCatalogCFG + 'qconsole.log'), Pchar(APath + 'qconsole.log'), true);
  AssignFile(urbanlog, APath + 'qconsole.log');
  if not FileExists(APath + 'qconsole.log')
      then
        begin
        Form1.Memo2.Font.Color:=clRed;
        Form1.Memo2.Lines.Add('Ошибка: Лог файл не найден, невозможно прочитать вывод сервера');
        end
      else
      begin
  Reset(urbanlog);
  while not Eof(urbanlog) do
    begin
      readln(urbanlog, log);
      Form1.Memo1.Lines.Add(log);
    end;
      CloseFile(urbanlog);
      end;
end;

Заранее благодарен за вашу помощь.
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Последний раз редактировалось lich100 08.11.2010 14:51:27, всего редактировалось 2 раз(а).
lich100
незнакомец
 
Сообщения: 4
Зарегистрирован: 08.11.2010 13:54:15

Re: Отслеживание изменений в файле и его вывод в мэмо

Сообщение Mr.Smart » 08.11.2010 14:42:01

Какая OC?
Mr.Smart
долгожитель
 
Сообщения: 1796
Зарегистрирован: 29.03.2008 01:01:11
Откуда: из леса!

Re: Отслеживание изменений в файле и его вывод в мэмо

Сообщение Padre_Mortius » 08.11.2010 14:44:58

Грузите файл в какой-нить TStringList или поток TStream. Запоминайте или номер последней строки или размер файла и начинайте чтение с этого момента
Padre_Mortius
энтузиаст
 
Сообщения: 1265
Зарегистрирован: 29.05.2007 17:38:07
Откуда: Спб

Re: Отслеживание изменений в файле и его вывод в мэмо

Сообщение coyot.rush » 08.11.2010 14:47:43

Как можно это реализовать

Если это лог то он имеет свойство увеличиваться, т.е.
1) нужно запомнить размер "старого" файла;
2) получть значение "нового";
3) затем считать "разницу" от конца файла.
Аватара пользователя
coyot.rush
постоялец
 
Сообщения: 309
Зарегистрирован: 14.08.2009 08:59:48

Re: Отслеживание изменений в файле и его вывод в мэмо

Сообщение lich100 » 08.11.2010 14:48:10

ОС Windows Seven.
lich100
незнакомец
 
Сообщения: 4
Зарегистрирован: 08.11.2010 13:54:15

Re: Отслеживание изменений в файле и его вывод в мэмо

Сообщение Mr.Smart » 08.11.2010 15:08:09

Как вариант для Windows NT можно использовать это http://msdn.microsoft.com/en-us/library/aa365465(VS.85).aspx
Mr.Smart
долгожитель
 
Сообщения: 1796
Зарегистрирован: 29.03.2008 01:01:11
Откуда: из леса!

Re: Отслеживание изменений в файле и его вывод в мэмо

Сообщение Odyssey » 08.11.2010 21:25:36

Если решать кроссплатформенно и в лоб, не заморачиваясь поначалу на быстродействие, я бы делал через TFileStream. Что-то типа:
Код: Выделить всё
var
  UrbanLog: TFileStream;
  LastLogSize: Int64;
  LogLine: String;
begin
  LastLogSize := 0;
//...
try
  UrbanLog := TFileStream.Create(APath + 'qconsole.log', fmOpenRead);
except
  on EFOpenError do ShowMessage('Ошибка: Не удалось открыть файл лога');
end;
if UrbanLog.Size > LastLogSize then
begin
  UrbanLog.Seek(LastLogSize);
  while (UrbanLog.Position < UrbanLog.Size) do
  begin
    LogLine := StreamReadLn(UrbanLog);
    Form1.Memo1.Lines.Add(LogLine);
  end;
  LastLogSize := UrbanLog.Size;
end;
FreeAndNil(UrbanLog);

Функция StreamReadLn - своя:
Код: Выделить всё
function StreamReadLn(AStream: TStream): string;
const
  CR = #13;
  LF = #10;
  cStrChunkSize = 255;
var
  buf: string;
  count: Integer;
  ch_prev, ch: char;
begin
  count   := 0;
  ch      := #0;
  ch_prev := #0;
  SetLength(buf, cStrChunkSize);
  while (AStream.Position < AStream.Size) do
  begin
    AStream.ReadBuffer(ch, SizeOf(ch));
    if (ch_prev = CR) then
    begin
      Dec(count);
      if (ch <> LF) then
        AStream.Seek(-1, soFromCurrent);
      Break;
    end else
    if (ch = LF) then
      Break
    else
    begin
      Inc(count);
      if Length(buf) < count then
        SetLength(AString, count + cStrChunkSize);
      buf[count] := ch;
      ch_prev := ch;
    end;
  end;
  SetLength(buf, count);
  Result := buf;
end;

Код писал сразу в браузер и не проверял. Поэтому за его работоспособность, скорость и качество не отвечаю.
Odyssey
энтузиаст
 
Сообщения: 580
Зарегистрирован: 29.11.2007 17:32:24


Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 20

Рейтинг@Mail.ru