【问题标题】:working of ObjectInputStreamObjectInputStream 的工作
【发布时间】:2011-06-19 02:54:36
【问题描述】:

我有多个对象存储在一个文件中。这是关于 ObjectInputStream。如果我有以下代码:

FileInputStream fis = new FileInputStream(filename);

ObjectInputStream ois = new ObjectInputStream(fis);

Object obj1 = (Object)ois.readObject();

ois.close();
 ois = new ObjectInputStream(fis);

Object obj2 = (Object)ois.readObject();

我的问题是:从第二个对象流 (obj2) 调用的 readObject 会是文件中的第一个还是第二个对象

【问题讨论】:

  • 不会ois.close(); 也关闭fis 吗?如果是这样,第二次读取可能会失败。
  • 如果我不关闭流,即。不要使用ois.close()。另外,如果我关闭 fis.close() 将同时关闭 ObjectInputStream

标签: java serialization objectinputstream


【解决方案1】:

它实际上会抛出一个异常。在 ObjectInputStream 上调用 close 也会关闭 FileInputStream。

【讨论】:

  • 如果我不关闭流,即。不要使用ois.close()。另外,如果我关闭 fis.close() 将同时关闭 ObjectInputStream
  • @Tarun 这行不通; ObjectInputStream 在内部进行缓冲。您要么需要继续使用相同的 ObjectInputStream,要么需要从新的 FileInputStream 重新开始。
  • @Tarun - 你有没有特别想解决的问题?听起来您希望能够在输入流中保留读取位置,以防崩溃或其他意外的文件流关闭。是这样吗?
【解决方案2】:

这取决于您存储对象的方式。如果你使用了一个 ObjectOutputStream,那么你最好也使用一个 ObjectInputStream。

如果您使用单独的流作为输出,您也应该使用单独的流作为输入。但这并不是真正推荐的。


对于您的“持久队列”,我建议如下:

发送方:

  • 创建一个 ByteArrayOutputStream,在其周围包裹一个 ObjectOutputStream。
  • 将对象写入OOS,并关闭OOS。
  • 获取byte[],并将其与指示队列流长度的标头一起写入。

在接收方:

  • 从队列流中读取标头长度。
  • 从队列流中读取给定长度的byte[]
  • 从这个数组创建一个 ByteArrayInputStream,并在它周围包裹一个 ObjectInputStream。
  • 从 OIS 读取一个对象,关闭 OIS。

当您存储部分队列时,请确保始终存储整个消息(即标头与对象一起)。

当然,使用现有的解决方案可能更容易,例如 JMS(您可以在其中创建 ObjectMessage,并将其提交到队列)。

【讨论】:

  • 基本上,我正在尝试创建一个持久队列。
  • @Tarun:对于持久队列,您可能希望使用单独的 ObjectOutputStreams。我刚刚编辑了一个可能的解决方案的答案。
猜你喜欢
  • 2012-01-12
  • 1970-01-01
  • 1970-01-01
  • 2013-08-29
  • 1970-01-01
  • 1970-01-01
  • 2019-06-07
  • 2020-05-13
  • 1970-01-01
相关资源
最近更新 更多