2017-02-04 74 views
0

我有一些我不明白,请帮助。ByteArrayInputStream到ObjectInputStream消失

System.out.println("\n" + Arrays.toString(buffer) + "\n"); 
System.out.println("buffer.length = " + buffer.length + "\nnew ByteArrayInputStream(buffer).available() is: " + new ByteArrayInputStream(buffer).available()); 
ObjectInput input = new ObjectInputStream(new ByteArrayInputStream(buffer)); 
System.out.println("input.available(): " + input.available()); 

其输出低于:

[-84, -19, 0, 5] 

buffer.length = 4 
new ByteArrayInputStream(buffer).available() is: 4 
input.available(): 0 

我很困惑,为什么4个的有效字节一个字节数组,投入的ObjectInputStream后,就变成零。

事情我已经尝试:

  1. 起初,我怀疑我的字节数组是空的,但正如你看到的,我打印出来,其长度为4
  2. 后来我想我的字节可能无效,所以我打印出每个字节,如你所见,这四个字节都是有效的。

因此,我迷失了为什么会发生这种情况。

请帮助,非常感谢!

+0

什么是输入数据?在4个字节处,它似乎不太可能是一个对象。正如文档所说,“ObjectInputStream反序列化先前使用ObjectOutputStream写入的原始数据和对象。” –

+0

如何显示输入?我认为Arrays.toString(缓冲区)是我能展示的最好的。 – FisherCoder

+0

所以在我以前的评论中有这个问题:'先前使用ObjectOutputStream编写的数据和对象'。你不这样做。您正在读取从未通过“ObjectInputStream”的原始字节。 –

回答

3

正如提到的其他答案,available仅表示在发生阻塞之前可以读取的字节数。

这是我的猜想,但是,你没有按照ObjectInputStream,其指定An ObjectInputStream deserializes primitive data and objects previously written using an ObjectOutputStream.

换句话说规则,实际上为了与ObjectInputStream读取数据,你首先必须有书面的该数据使用某种ObjectOutputStream。这里是显示这个与你提供的数据为例:(我要补充一点,我很少与IO在Java中工作,因此上述可能不是最好的做法或有多余的代码)

byte[] buffer = new byte[]{-84,-19,0,5}; 
ByteArrayOutputStream out = new ByteArrayOutputStream(); 
ObjectOutputStream objectOutputStream= new ObjectOutputStream(out); 
objectOutputStream.write(buffer); 
objectOutputStream.flush(); 

ObjectInput input = new ObjectInputStream(new ByteArrayInputStream(out.toByteArray())); 
System.out.println("input.available(): " + input.available()); 
System.out.println("input.readByte(): " + input.readByte()); 

+0

感谢您指出,它绝对加深了我的理解!^^ – FisherCoder

1

Hereavailable方法的javadoc的,这就是它说:

返回可以无阻塞地读取的字节数。

所以,它不会返回bytes目前总数数组中/读,它返回的bytes它可以被阻塞之前阅读次数。所以,它返回0是一个有效的场景。

现在,让我们来看看ObjectInputStream javadoc的,这里是简要说明:

非对象读取超出分配的数据到底会 反映的数据以同样的方式结束他们会指示 流的结束:字节读取将返回-1作为字节读取或 读取的字节数,原语读取将抛出EOFExceptions。如果 没有相应的writeObject方法,则默认的 序列化数据结束标记分配数据的结束。

什么你想在你的代码做的是read原始数据(或读不WriteObject法),因为它是无效的数据(ObjectInputStreamread总是返回-1。我只能通过调用readObject方法来重现EOFException

我又试图写入/读取一个新的对象和测试available方法调用,看看下面的代码片段:

byte[] buffer = new byte[]{-84, -19, 0, 5}; 
System.out.println("\n" + Arrays.toString(buffer) + "\n"); 
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(buffer); 
System.out.println("buffer.length = " + buffer.length + "\nnew ByteArrayInputStream(buffer).available() is: " + new ByteArrayInputStream(buffer).available()); 
ObjectInputStream input = new ObjectInputStream(byteArrayInputStream); 
System.out.println("input.available(): " + input.available()); 
//  System.out.println(input.readObject()); //Uncomment to see EOFException 

Date date = new Date(); 
System.out.println(date); 
ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream(); 
ObjectOutputStream out = new ObjectOutputStream(byteArrayOut); 
out.writeObject(date); 
byte[] bytes = byteArrayOut.toByteArray(); 

input = new ObjectInputStream(new ByteArrayInputStream(bytes)); 
System.out.println(input.available()); 
System.out.println(input.readObject()); 

代码reads已经写对象,并输出值。请注意,即使它正确读取对象并打印相同的对象,available方法仍会返回0。所以,我建议不要过于依赖available,因为它是误导性的名称:)