java – 从随机访问文件中读取对象

我使用Java的FileChannel类编写了一个使用RandomAccessFiles的文件.我在文件的不同位置写了对象.对象的大小可变,但所有类都相同.我使用以下想法编写了对象:

ByteArrayOutputStream bos= new ByteArrayOutputStream();
        ObjectOutput out = new ObjectOutputStream(bos);
        out.writeObject(r);
        byte[] recordBytes= bos.toByteArray();
    ByteBuffer rbb= ByteBuffer.wrap(recordBytes);

    while(rbb.hasRemaining()) {
        fileChannel.write(rbb);
    }

现在我想从这样的文件中读取.我不想指定要读取的字节数.我希望能够使用Object Input Stream直接读取对象.怎么做到这一点?

我必须使用随机访问文件,因为我需要写入文件中的不同位置.我也在一个单独的数据结构中记录,即写入对象的位置.

解决方法:

I have to use Random Access Files because I need to write to different
positions in file.

不,你没有.您可以通过其通道重新定位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中.在这种特定情况下,在每次使用之前重新定位文件流,这可以提供性能优势.但请注意,缓冲流可以读取比所需更多的字节,并且在某些情况下使用构造所需的对象流,这将是一个非常糟糕的主意.

上一篇:序列化集合


下一篇:Socket上的Java ObjectOutputStream不是flush()ing