如何读取DataInputStream两次或两次以上?

时间:2016-02-08 13:29:52

标签: java android sockets datainputstream

我有一个Socket连接到我在其他地方托管的应用程序。连接后,我制作了OutputStreamDataInputStream

连接完成后,我使用OutputStream向应用程序发送握手数据包。一旦此握手获得批准,它将通过DataInputStream(1)返回一个数据包。

处理此数据包并使用OutputStream将其返回给应用程序。

如果返回的数据有效,我会从DataInputStream(2)获得另一个数据包。但是,我无法通过DataInputStream读取此数据包。

我尝试使用DataInputStream.markSupported()DataInputStream.mark()但这没有给我任何信息(除了一个空的Exception消息)。

是否可以再次读取输入流?如果是这样,有人可以指出我在这里做错了吗?

编辑:这是我的解决方案:

// First define the Output and Input streams.
OutputStream output = socket.getOutputStream();
BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());

// Send the first packet to the application.
output.write("test"); // (not actual data that I sent)

// Make an empty byte array and fill it with the first response from the application.
byte[] incoming = new byte[200];
bis.read(incoming); //First packet receive

//Send a second packet to the application.
output.write("test2"); // (not actual data that I sent)

// Mark the Input stream to the length of the first response and reset the stream.
bis.mark(incoming.length);
bis.reset();

// Create a second empty byte array and fill it with the second response from the application.
byte[] incoming2 = new byte[200];
bis.read(incoming2);

我不确定这是否是最正确的方法,但这种方式对我有用。

2 个答案:

答案 0 :(得分:2)

我会使用ByteArrayInput流或你可以重置的东西。这将涉及将数据读入另一种类型的输入流,然后创建一个。

InputStream有一个markSupported()方法,您可以检查原始方法和字节数组,找到一个标记可以使用的方法:

https://docs.oracle.com/javase/7/docs/api/java/io/InputStream.html#markSupported() https://docs.oracle.com/javase/7/docs/api/java/io/ByteArrayInputStream.html

答案 1 :(得分:1)

这里的问题不是重新读取输入。我不会在问题中看到任何需要您阅读输入两次的内容。问题是BufferedInputStream,将读取可以读取的所有内容,包括第二条消息(如果已经到达)。

解决方案是在完成握手之前不要使用缓冲流。只需在套接字输入流上发出一个读取,确切地知道第一条消息的长度,进行握手,然后继续构造并读取缓冲的流。