У меня есть требование записать записи в файл, где данные записываются в местоположении файла (т.е. в позиции поиска) в зависимости от значения числового ключа. Например, если ключ равен 100, я могу записать в позиции 400.
Записи состоят из числового ключа и части данных. Запись не будет очень большой (несколько байтов). Однако может быть много записей (миллионов).
Возможны два сценария:
-
Ключи монотонно увеличиваются. В этом случае наилучшим подходом является запись с использованием
DataOutputStream
wrapping aBufferedOutputStream
, установка размера буфера на некоторое число (например, 64k), чтобы максимизировать пропускную способность ввода-вывода. -
Клавиши увеличиваются, но возможны большие пробелы. В этом случае использование OutputStream потребует, чтобы нули записывались в промежутках в файле. Чтобы избежать этого,
RandomAccessFile
будет лучше, поскольку он может искать пробелы, экономя пространство, если можно запросить весь блок. Недостатком является то, что, насколько мне известно,RandomAccessFile
не буферизуется, поэтому этот метод будет медленным для последовательных ключей.
Однако, вероятная ситуация заключается в том, что файл немного для обоих. Есть последовательности монотонно увеличивающих ключей. Есть несколько ключей с небольшими промежутками между и другими с очень большими пробелами.
То, что я ищу, - это решение, которое дает лучшее из обоих миров. Возможно, я переключаюсь между двумя режимами ввода/вывода, если обнаружен разрыв между ключами. Однако было бы лучше, если бы был стандартный Java-класс, который может выполнять обе эти вещи. Я видел FileImageOutputStream
, но я не уверен, как это работает.
Обратите внимание, что я не ищу образцы кода (хотя это было бы полезно для демонстрации сложных решений), а всего лишь общая стратегия. Было бы хорошо знать размеры буферов оптимального размера для последовательных данных и в какой момент (размер разрыва) вам нужно перейти от последовательной стратегии к стратегии произвольного доступа.
EDIT:
Чтобы ответ был принят, я хотел бы получить некоторую уверенность в том, что предлагаемое решение обрабатывает оба, а не только то, что оно может. Для этого потребуется:
- Подтверждение буферизации последовательного режима.
- Подтверждение того, что режим произвольного доступа оставляет дыры в файле.
Кроме того, решение должно быть эффективным с точки зрения памяти, так как многие из этих файлов могут открываться одновременно.
РЕДАКТИРОВАТЬ 2
Файлы могут быть на NAS. Это не дизайн, а просто признание того, что в корпоративной среде эта архитектура используется много, и решение должно, вероятно, справиться с ней (возможно, не оптимально), а не предотвращать ее использование. AFAIK, это не должно влиять на решение, основанное на write()
и lseek()
, но может привести к недействительности некоторых более эзотерических решений.