Конверсия java FileDescriptor .sync () для * чтения * файлов - PullRequest
2 голосов
/ 18 июня 2009

При чтении javadoc в методе FileSesciptor .sync () очевидно, что sync () в первую очередь касается фиксации любых измененных буферов обратно в основное хранилище. То есть, убедившись, что все, что у вашей программы есть вывод , действительно попадет на диск (или в сокет или что-то еще, но мой вопрос касается в основном дисков).

А как насчет другого направления, а как насчет INPUT? Предположим, что в моей программе есть некоторые части файла java.io.RandomAccessFile, буферизованные в памяти, и я хочу ПРОЧИТАТЬ эти части файла, но, возможно, какой-то другой процесс изменил эти части файла после того, как моя программа прочитала эти блоки в последний раз?

Это похоже на пометку переменной как 'volatile' в программе на Си; что-то еще, возможно, изменило «реальную версию» чего-то, что у вас просто есть удобная копия.

Т.е., как вы можете быть уверены, что то, что читает ваша Java-программа, по крайней мере достаточно современно?

(Понятно, что определение «актуальная» имеет значение. Чисто в качестве примера, предположим, что другой процесс, тот, который записывает в файл, делает это примерно раз в секунду, и предположим, что чтение Процесс считывает, может быть, один раз в минуту. В такой ситуации производительность не имеет большого значения, просто нужно убедиться, что то, что читает читатель, согласуется с тем, что пишет пишет, с точностью до секунды.)

Ответы [ 3 ]

2 голосов
/ 18 июня 2009

Перед повторным чтением вашего файла обычно рекомендуется проверить последнюю измененную временную метку файла с помощью File.lastModified (). Если эта временная метка не новее, чем в последний раз, когда вы читаете файл, вам не нужно беспокоиться о большем количестве дискового ввода-вывода, чтобы перечитать интересующие вас блоки. Однако следует помнить, последняя измененная временная метка не всегда может обновляться сразу после обновления содержимого, если вы используете сетевую файловую систему. Если вы имеете дело с локальным процессом, обновляющим файл, и другим локальным процессом, выполняющим ваш код, читающий файл, вы, скорее всего, не столкнетесь с этой проблемой.

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

1 голос
/ 18 июня 2009

В тот момент, когда файл считывается во внутренний буфер, его содержимое соответствует содержимому на диске.

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

Конечно, ваша производительность ухудшится, если вы получите доступ к диску при каждом доступе к данным. Не думайте о 3-5 раз или около того, но порядки величин.

0 голосов
/ 19 июня 2009

Если другая программа, которой вы управляете, является единственной записывающей в файл, то, вероятно, лучше иметь 2 потока с одинаковыми координатами процесса Java. Самое простое решение - создать java.util.concurrrent.atomic.AtomicBoolean. Запись потока вызывает set(true) на AtomicBoolean, а читатель вызывает getAndSet(false). Если getAndSet() возвращает true, то вы знаете, что читателю необходимо перечитать данные. Если это проблема, вы можете выполнить синхронизацию на каком-либо объекте, чтобы предотвратить запись писателя во время чтения.

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

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