Как написать файл, который читается?

Мое приложение медленно читает TextFile чисел с плавающей точкой. Время от времени обстоятельства меняются, и файл должен быть переписан. Пример кода:

procedure TAMI_Column_Selector.read_continuously (file_name: string);
var infile: TextFile;
    f: Double;
begin
   AssignFile (infile, file_name);
   Reset (infile);
   try
      while not EOF (infile) do
      begin
         Read (infile, f);
         process (f); // this may take quite some time, seconds or even minutes
      end; // while
   finally
      CloseFile (infile);
   end; // try..finally
end; // read_continuously //

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

  1. Как я могу написать файл, который открыт для чтения?
  2. как предотвратить сбой, когда приложение пытается прочитать файл, который в данный момент записывается
  3. как мое приложение узнает, что файл был переписан?

Я думаю, что я мог бы решить в первую очередь вопросы чтения файла в память и чтения этого (есть ли TextFile, который можно записывать и читать из памяти)? Тогда все еще остается, как я могу проверить файл был переписан.

У кого-нибудь есть (элегантное) решение этой проблемы?

Заранее спасибо.

Использование Delphi XE на Windows 7

1 ответ

Решение

Для записи в файл, который также открыт для чтения, обычно автор не должен делать ничего особенного. Если все остальные, у кого открыт файл, разрешили запись в файл, то предполагаемый автор может открыть файл для записи, выполнить запись в файл и закрыть его. Если другие не разрешили запись в файл, то предполагаемому автору не будет разрешено открыть файл, и он ничего не может с этим поделать.

То, как открыть файл для чтения, а также разрешить запись, зависит от используемого метода открытия. С CreateFile, параметр dwDesiredAccess является обычным GENERIC_READ и параметр dwShareMode имеет значение FILE_SHARE_READ or FILE_SHARE_WRITE, Если вы используете TFileStream, тогда параметр режима конструктора должен быть fmOpenWrite or fmShareDenyNone, Если вы используете AssignFile а также Reset тогда вам нужно установить FileMode глобальная переменная, но она не поддерживает режимы совместного использования, поэтому вы не можете использовать ввод-вывод в стиле Pascal.

Чтение файла, который записывается одновременно, по своей сути не вызывает сбой. Это, конечно, не вызывает проблем на уровне ОС. Если ваша программа дает сбой, это потому, что она не была написана, чтобы предвидеть сбои чтения. Когда вы что-то читаете, проверьте результат API, чтобы убедиться, что вы прочитали столько байтов, сколько запросили. Вы также можете использовать приложения для чтения и письма друг с другом. Вы можете использовать объект синхронизации для сериализации доступа к файлу, или писатель может отправить читателю сигнал, указывающий, что файл изменился и что предыдущее чтение может быть неточным. Это зависит от вас, чтобы проработать детали.

Если читатель собирается сохранить копию файла в памяти, то ему, вероятно, не нужно беспокоиться о совместном доступе к записи. Вместо этого он может открыть файл и предоставить доступ только для чтения, сделать копию файла в памяти и закрыть файл. Затем автор может открыть файл, не беспокоясь о том, чтобы растоптать процесс чтения, потому что попирать нечего. Он может уведомить читателя о том, что что-то изменилось, и читатель может либо перезагрузить весь файл, либо просто загрузить измененную часть. (Автор должен будет сказать читателю, какая часть изменилась, однако у читателя нет другого способа обнаружить это, не прочитав весь файл и не увидев, чем он отличается от копии в памяти.)

Другой способ предотвратить вмешательство записей в чтение - использовать транзакции. Однако транзакционная NTFS постепенно сокращается. Microsoft опубликовала список альтернатив, поэтому вы можете попытаться найти то, что соответствует вашим потребностям.

Другие вопросы по тегам