Как надежно прочитать данные из файла, который постоянно записывается другим процессом? - PullRequest
0 голосов
/ 08 января 2019

Итак, я нахожусь в ситуации, когда один процесс непрерывно (через каждые несколько секунд) записывает данные в файл (не добавляя). Данные в форме JSON. Теперь другой процесс должен читать этот файл через равные промежутки времени. Теперь может случиться так, что процесс чтения читает его, пока процесс записи пишет в файл.

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

Или, возможно, лучшим решением будет прочитать файл дважды после определенного периода времени (намного меньше, чем интервал записи в процессе записи) и посмотреть, совпадают ли прочитанные данные.

Третий способ - записать некоторые магические данные в конец файла, чтобы процесс чтения знал, что он прочитал весь файл, если он принял эти магические данные в конце.

Что ты думаешь? Являются ли эти решения жизнеспособными, или есть лучшие методы для достижения этого?

Ответы [ 2 ]

0 голосов
/ 08 января 2019

Создайте новый файл каждый раз, и rename() новый файл, как только он будет полностью записан:

Если newpath уже существует, он будет атомарно заменен, так что нет точки, в которой другой процесс пытается получить доступ newpath найдет его отсутствующим. ...

Некоторая копия файла всегда будет там, и она всегда будет полной и правильной:

Итак, вместо

writeDataFile( "/path/to/data/file.json" );

и затем, пытаясь понять, что делать в процессе (ах) чтения, вы просто делаете

writeDataFile( "/path/to/data/file.json.new" );
rename( "/path/to/data/file.json.new", "/path/to/data/file.json" );

Нет необходимости в блокировке, ни в чтении файла, ни в вычислении контрольных сумм и в надежде, что это правильно.

Единственная проблема заключается в том, что любой процесс чтения должен open() файл каждый раз, когда ему нужно прочитать последнюю копию - он не может сохранить и открыть дескриптор файла в файле и попытаться прочитать новое содержимое как rename() call отменяет связь с исходным файлом и заменяет его совершенно новым файлом.

0 голосов
/ 08 января 2019

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

mkfifo ./jsonoutput

Затем задайте одну программу для записи, а другую - для чтения из этого файла ./jsonoutput.

Пока писатель регулярно закрывает и снова открывает файл после записи каждого JSON, читатель получит EOF и обработает ввод.

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...