Я должен использовать файлы произвольного доступа, потому что мне нужно записывать
позиции в файле.
Нет, нет. Вы можете изменить положение FileOutputStream
или FileInputStream
через его канал.
Это также значительно упростит ваш код написания: вам не нужно будет использовать буфер или канал, и в зависимости от ваших потребностей вы также можете опустить ByteArrayOutputStream
. Однако, как вы заметили в комментарии, вы заранее не будете знать размер объекта, и ByteArrayOutputStream
- это полезный способ убедиться, что вы не переполните выделенное пространство.
Object obj = // something
FileOutputStream fos = // an initialized stream
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(obj);
oos.flush();
if (bos.size() > MAX_ALLOWED_SIZE)
throw // or log, or whatever you want to do
else
{
fos.getChannel().position(writeLocation);
bos.writeTo(fos);
}
Чтобы прочитать объекты, сделайте следующее:
FileInputStream fis = // an initialized stream
fis.getChannel().position(offsetOfSerializedObject);
ObjectInputStream iis = new ObjectInputStream(new BufferedInputStream(fis));
Object obj = iis.readObject();
Один комментарий здесь: я завернул FileInputStream
в BufferedInputStream
. В этом конкретном случае, когда файловый поток перемещается перед каждым использованием, это может обеспечить выигрыш в производительности. Имейте в виду, однако, что буферизованный поток может читать больше байтов, чем необходимо, и в некоторых ситуациях используются потоки объектов конструкции по мере необходимости, где это будет действительно плохой идеей.