如何在更改底层 FileInputStream 的位置后重置 BufferedInputStream
How to reset a BufferedInputStream after changing the underlying FileInputStream's position
我正在尝试对文件中的可序列化对象执行随机 read/write 操作。
我知道我可以设置 FileInputStream
的位置,然后像这样在其周围包裹适当的输入流:
InputStream file = new FileInputStream(fileName);
((FileInputStream)file).getChannel().position(pos);
InputStream buffer = new BufferedInputStream(file);
ObjectInput input = new ObjectInputStream (buffer);
但是,如果稍后我必须再次更改 FileInputStream
的位置以执行另一个写入操作怎么办?
如何 change/reset BufferedInputStream
才能正确执行?我什至必须这样做吗?
另外,我假设这个问题的任何答案也适用于输出场景?!
我认为您可以做的更简单的事情是在您需要移动 FileInputStream
上的位置时创建一个新的 BufferedInputStream
。
I'm trying to perform random read/write operations on serializable objects in a file.
就在那儿停下(然后后退)。你不能通过任何方式做到这一点。对于 类 和 object,object 流依赖于它自己过去的历史,通过 'handles' 系统。您通常不会成功,但是您尝试在代码中实现它,例如,通过消除缓冲流。
EDIT 序列化不会 re-serialize 已经序列化 object。例如,一个 StreamClassDesc
,它随每个 object 一起提供。相反,它只是将 'handle' 序列化为它。所以即使你只是序列化两个 Strings
,你也不能单独反序列化第二个,因为 classdesc 句柄引用了流中的前一个 object。请参阅 Object 序列化规范。还有流 header 需要考虑。
我同意 EJP:如果您要求 "generic" 适用于任意 classes 的解决方案,那么您在这里走错了兔子洞。
但是您的评论清楚地表明,您专门设计了 class(es) 以在使用序列化 正确 时导致 "equally sized records"。
您需要做的事情:
- 忘记使用 FileInput/OutputStream,而是:
- 使用 RandomAccessFile - 因为它允许您在文件中的随机点读取/写入字节
- 对于每个要处理的对象,使用其自己的,专用的
ByteArrayInputStream(相应输出)对象。
换句话说:为了完成这项工作,一次拍摄中不能 read/write 多个对象。您希望序列化是一种将单个对象转换为字节流的简单机制;反之亦然。
但请记住:您会为非常有限的用例花费大量精力。一旦您的 classes 需要变得更复杂,您就会 broken - 因为您现在最终得到 different 大小的字节交涉。
所以真正的答案在这里:虽然你的想法可以实现(并且是一个很好的关于序列化和文件访问的学习练习),但你正在重新发明轮子!而且您的那个轮子的版本非常有限,很难增强;并可能导致表现平平。
因此,如果这是针对 "real" 产品的:最好转向任何 真实的 数据库,而不是构建您自己的 DBMS。
我正在尝试对文件中的可序列化对象执行随机 read/write 操作。
我知道我可以设置 FileInputStream
的位置,然后像这样在其周围包裹适当的输入流:
InputStream file = new FileInputStream(fileName);
((FileInputStream)file).getChannel().position(pos);
InputStream buffer = new BufferedInputStream(file);
ObjectInput input = new ObjectInputStream (buffer);
但是,如果稍后我必须再次更改 FileInputStream
的位置以执行另一个写入操作怎么办?
如何 change/reset BufferedInputStream
才能正确执行?我什至必须这样做吗?
另外,我假设这个问题的任何答案也适用于输出场景?!
我认为您可以做的更简单的事情是在您需要移动 FileInputStream
上的位置时创建一个新的 BufferedInputStream
。
I'm trying to perform random read/write operations on serializable objects in a file.
就在那儿停下(然后后退)。你不能通过任何方式做到这一点。对于 类 和 object,object 流依赖于它自己过去的历史,通过 'handles' 系统。您通常不会成功,但是您尝试在代码中实现它,例如,通过消除缓冲流。
EDIT 序列化不会 re-serialize 已经序列化 object。例如,一个 StreamClassDesc
,它随每个 object 一起提供。相反,它只是将 'handle' 序列化为它。所以即使你只是序列化两个 Strings
,你也不能单独反序列化第二个,因为 classdesc 句柄引用了流中的前一个 object。请参阅 Object 序列化规范。还有流 header 需要考虑。
我同意 EJP:如果您要求 "generic" 适用于任意 classes 的解决方案,那么您在这里走错了兔子洞。
但是您的评论清楚地表明,您专门设计了 class(es) 以在使用序列化 正确 时导致 "equally sized records"。
您需要做的事情:
- 忘记使用 FileInput/OutputStream,而是:
- 使用 RandomAccessFile - 因为它允许您在文件中的随机点读取/写入字节
- 对于每个要处理的对象,使用其自己的,专用的
ByteArrayInputStream(相应输出)对象。
换句话说:为了完成这项工作,一次拍摄中不能 read/write 多个对象。您希望序列化是一种将单个对象转换为字节流的简单机制;反之亦然。
但请记住:您会为非常有限的用例花费大量精力。一旦您的 classes 需要变得更复杂,您就会 broken - 因为您现在最终得到 different 大小的字节交涉。
所以真正的答案在这里:虽然你的想法可以实现(并且是一个很好的关于序列化和文件访问的学习练习),但你正在重新发明轮子!而且您的那个轮子的版本非常有限,很难增强;并可能导致表现平平。
因此,如果这是针对 "real" 产品的:最好转向任何 真实的 数据库,而不是构建您自己的 DBMS。