从随机访问文件中读取对象
我使用 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);
}
现在我想读取这样的文件。我不想指定要读取的字节数。我希望能够使用对象输入流直接读取对象。如何实现这一目标?
我必须使用随机访问文件,因为我需要写入文件中的不同位置。我还在一个单独的数据结构中记录对象被写入的位置。
I wrote a file using Java's FileChannel class that uses RandomAccessFiles. I wrote objects at various locations in the file. The objects were of variable sizes but all of the same class. I wrote the objects using the following idea :
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); }
Now I want to read from such a file. I dont want to have to specify the number of bytes to read. I want to be able to read the object directly using Object Input Stream. How to achieve this ?
I have to use Random Access Files because I need to write to different positions in file. I am also recording in a separate data structure, the locations where objects have been written.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
不,你不知道。您可以通过其通道重新定位
FileOutputStream
或FileInputStream
。这也将显着简化您的编写代码:您不需要使用缓冲区或通道,并且根据您的需要,您也可以省略 ByteArrayOutputStream 。但是,正如您在评论中指出的那样,您不会提前知道对象的大小,并且 ByteArrayOutputStream 是验证您没有超出分配空间的有用方法。
要读取对象,请执行以下操作:
这里有一条注释:我将
FileInputStream
包装在BufferedInputStream
中。在这种特定情况下,文件流在每次使用之前都会重新定位,这可以提供性能优势。但是请注意,缓冲流可以读取比需要的更多的字节,并且在某些情况下使用按需构造对象流,这将是一个非常糟糕的主意。No, you don't. You can reposition a
FileOutputStream
orFileInputStream
via its channel.That would significantly simplify your writing code as well: you wouldn't need to use the buffer or channel, and depending on your needs you could omit the
ByteArrayOutputStream
as well. However, as you note in a comment, you won't know the size of the object in advance, and theByteArrayOutputStream
is a useful way to verify that you don't overrun your allotted space.To read the objects, do the following:
One comment here: I wrapped the
FileInputStream
in aBufferedInputStream
. In this specific case, where the file stream is repositioned before each use, that can provide a performance benefit. Be aware, however, that the buffered stream can read more bytes than are needed, and there are some situations using construct-as-needed object streams where it would be a really bad idea.为什么不寻找 为你工作吗?我相信您需要
seek()
来纠正位置,然后使用对象流读取对象。另外,如果您存储序列化对象的正确位置,为什么不存储它们的大小呢?在这种情况下,您可以对从文件读取的字节应用ObjectInputStream
。Why doesn't seek work for you? I believe you need to
seek()
to correct locations and then just read objects using your object stream. Also, if you store the correct locations of serialized objects, why don't you store their sizes? In this case you may applyObjectInputStream
against bytes you read from file.想到的最简单的解决方案是在写出数组本身之前写出数组的长度:
读取对象时,首先读取长度。这将告诉您还需要读取多少字节才能获取对象。与您在写入方面已经执行的操作类似,您可以将数据读取到
byte[]
中,然后使用ByteArrayInputputStream
和ObjectInputStream
。The simplest solution that comes to mind is to write out the length of the array before writing out the array itself:
When reading the object, you first read the length. This'll tell you how many further bytes to read to get your object. Similarly to what you are already doing on the writing side, you could read the data into a
byte[]
and then useByteArrayInputputStream
andObjectInputStream
.您可以使用在
RandomAccesFile
的FileDescriptor
对象上构造的FileInputStream
,如下所示:假设 RandomAccessFile 名为 raf。
You could use a
FileInputStream
constructed on theRandomAccesFile
'sFileDescriptor
object, like so:Assuming that the RandomAccessFile is called raf.