Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 4 336

/ вопрос открыт /

Здравствуйте, уважаемые эксперты!
Такая ситуация: есть лог файл, который постоянно дописывается (его ведет сторонняя программа, периодически его дописывая с разным интервалом времени ). Так как нет определенного времени по которому она дописывает файл , приходится его всегда читать. Возникает проблема, если читать в тот момент когда происходит запись, вылетает ошибка "raised exception class EInOutError witch message 'I/O error 32".
Возможно ли определить момент записи файла сторонней программой и в этот момент не читать? Либо другие способы для решения этой проблемы.

mr_switch Вопрос ожидает решения (принимаются ответы, доступен мини-форум)

Вопрос задал: mr_switch (статус: Посетитель)
Вопрос отправлен: 17 июня 2010, 05:00
Состояние вопроса: открыт, ответов: 2.

Ответ #1. Отвечает эксперт: Егор

Здравствуйте, mr_switch!
Можно выключать выдачу исключений с помощью команд {$1-} / {$i+}, а проверку успешности открытия файла осуществлять с помомщьдю функции IOResult (подход, свойственный Паскалю):

...
{$I-} // выключили прерывания по ошибкам ввода-вывода
      // пробелы перед открывающей фигурной скобкой в начале строки должны отсутствовать!
  ... // здесь попытались открыть файл
{$I+} // включили обратно прерывания по ошибкам ввода-вывода
  if IOResult=0 then // если ошибок при открытии не было
    begin
      ... // код обработки файла
    end
  else
    begin
      ... // код обработки ошибки открытия файла
    end;
...

Другой подход, свойственный программированию под дельфи - обернуть "опасный" участок в блок try...except или try...finally:
...
  try
    ... // открываем файл, обрабатываем его
  except
    on EInOutError do
      begin
        ... // открыть файл не удалось. здесь обрабатываем ошибку
      end;
  end;

Ответ отправил: Егор (статус: 10-ый класс)
Время отправки: 17 июня 2010, 05:30
Оценка за ответ: 4

Комментарий к оценке: все та же ошибка вылетает

Ответ #2. Отвечает эксперт: min@y™

Вот это КОД!!! Лучше б не показывал! Убери его отсюда, не позорься. А у себя в программе замени это безобразие на

procedure TForm1.Timer2Timer(Sender: TObject);
begin
  try
    cmd.Lines.LoadFromFile('C:\log\log.csv');
  except
    cmd.Lines.Text:= 'err open';
  end;
end;

Ответ отправил: min@y™ (статус: Доктор наук)
Время отправки: 17 июня 2010, 13:01
Оценка за ответ: 4

Комментарий к оценке: теперь вылетает такая ошибка: "raised exception class EFOpenError with message 'Cannot open file "C:\log\log.csv". Процесс не может получить доступ к файлу, так как этот файл занят другим процеccом'.

Мини-форум вопроса

Всего сообщений: 7; последнее сообщение — 21 июня 2010, 17:27; участников в обсуждении: 3.
Егор

Егор (статус: 10-ый класс), 17 июня 2010, 05:36 [#1]:

блин, в ответе ошибся. Вот так без ошибки:
"Можно выключать выдачу исключений с помощью команд {$I-} / {$I+}
Опасайтесь багов в приведенном выше коде; я только доказал корректность, но не запускал его.
— Donald E. Knuth.
min@y™

min@y™ (статус: Доктор наук), 17 июня 2010, 08:12 [#2]:

Покажи код чтения файла.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
mr_switch

mr_switch (статус: Посетитель), 17 июня 2010, 12:52 [#3]:

procedure TForm1.Timer2Timer(Sender: TObject);
var
t1:TextFile;
s:String;
begin
cmd.Lines.Clear;
try
AssignFile(t1, 'C:\log\log.csv');
Reset(t1);
while not(Eof(t1)) do
begin
Readln(t1, s);
cmd.Lines.Add(s);
end;
CloseFile(t1);
except
on EInOutError do
begin
cmd.Lines.Add('err open');
end;
end;

end;

Вставил в блок try...except не помогло , все та же ошибка вылетает.
mr_switch

mr_switch (статус: Посетитель), 18 июня 2010, 17:28 [#4]:

изначально было так:
procedure TForm1.Timer2Timer(Sender: TObject);
begin
cmd.Lines.LoadFromFile('C:\log\log.csv');
end;

потом изменил на то что выше....

сейчас сделал вот-так:
procedure TForm1.Timer2Timer(Sender: TObject);
begin
try
cmd.Lines.LoadFromFile('C:\log\log.csv');
except
cmd.Lines.Text:= 'err open';
end;
end;

теперь вылетает такая ошибка: "raised exception class EFOpenError with message 'Cannot open file "C:\log\log.csv". Процесс не может получить доступ к файлу, так как этот файл занят другим процеccом'.

Как перед открытием файла определить, не открыт ли он другой программой ?
min@y™

min@y™ (статус: Доктор наук), 18 июня 2010, 17:38 [#5]:

Цитата (mr_switch):

теперь вылетает такая ошибка: "raised exception class EFOpenError with message 'Cannot open file "C:\log\log.csv". Процесс не может получить доступ к файлу, так как этот файл занят другим процеccом'.

Как перед открытием файла определить, не открыт ли он другой программой ?


Ну и за что 4 балла? Я же не знал, что у тебя включена галочка "Tools/Debugger options/Language exceptions/Stop on Delphi exceptions"! Я, блин, не телепат.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
min@y™

min@y™ (статус: Доктор наук), 18 июня 2010, 17:45 [#6]:

Цитата (min@y™):

Как перед открытием файла определить, не открыт ли он другой программой ?

Да хоть вот так:
function FileIsOpen(const Filename: String): Boolean;
var
   Datei: TFileStream;
begin
  result:= FALSE; 
  if FileExists(Filename) then begin
    try
      Datei:= TFileStream.Create(Filename, fmOpenRead);
      Datei.Free;
    except
      on EFOpenError do result:= true;
    end;
  end;
end;
Взято из Delphi works.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
mr_switch

mr_switch (статус: Посетитель), 21 июня 2010, 17:27 [#7]:

min@y™: убрал "Tools/Debugger options/Language exceptions/Stop on Delphi exceptions" ошибка не вылетает . пока все ок. Спасибо за помощь и за функцию, она еще пригодится.

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:59
Выполнено за 0.03 сек.