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