来自Socket的DataInputStream的“可用”

我在客户端有这个代码:

DataInputStream dis = new DataInputStream(socketChannel.socket().getInputStream()); while(dis.available()){ SomeOtherClass.method(dis); } 

但是,尽管流中有可读数据,但available()仍然返回0 。 因此,在完成要读取的实际数据之后,将空数据传递给另一个要读取的类,这会导致损坏。

经过一番搜索; 我发现在使用套接字时, available()是不可靠的,我应该从流中读取前几个字节,以实际查看数据是否可用于解析。

但就我而言; 我必须将我从套接字获得的DataInputStream引用传递给其他一些我无法更改的类。

是否可以从DataInputStream读取几个字节而不破坏它或任何其他建议?

在它们之间放置PushbackInputStream允许您读取一些字节而不会破坏数据。

编辑:下面未经测试的代码示例。 这是来自记忆。

 static class MyWrapper extends PushbackInputStream { MyWrapper(InputStream in) { super(in); } @Override public int available() throws IOException { int b = super.read(); // do something specific? super.unread(b); return super.available(); } } public static void main(String... args) { InputStream originalSocketStream = null; DataInputStream dis = new DataInputStream(new MyWrapper(originalSocketStream)); } 

这应该工作:

 PushbackInputStream pbi = new PushbackInputStream(socketChannel.socket().getInputStream(), 1); int singleByte; DataInputStream dis = new DataInputStream(pbi); while((singleByte = pbi.read()) != -1) { pbi.unread(singleByte); SomeOtherClass.method(dis); } 

但是请注意,此代码的行为与可用的示例(如果availablebe可行)不同,因为available不会阻塞但read可能会阻塞。

但是,尽管流中有可读数据,但available()仍然返回0

如果available()返回零,则:

  1. 您正在使用的输入流不支持available() ,因此它只返回零。 这不是这里的情况,因为您使用直接包装在套接字输入流中的DataInputStream ,并且该配置支持available() ,OR …

  2. 流中没有可读数据。 这似乎就是这种情况。 实际上,您可以知道流中可读数据的唯一可能方式是调用available()并获得正结果。 没有其他说法。

availabe()正确用法很少,而这不是其中之一。 为什么你应该因为套接字接收缓冲区中没有任何数据而退出该循环? 你应该摆脱这种循环的唯一方法是获得流结束条件。

我应该从流中读取前几个字节,以实际查看数据是否可用于解析。

这甚至没有意义。 如果您可以从流中读取任何内容,则可以获得数据,如果不能,则不会。

只需在各种表现forms中读取,阻止并正确响应EOS即可。