来自Socket的DataInputStream“可用”

时间:2012-08-16 07:41:10

标签: java sockets datainputstream

我在客户端有这个代码:

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

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

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

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

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

3 个答案:

答案 0 :(得分:4)

在其间放置一个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));
}

答案 1 :(得分:2)

这应该有效:

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可能会阻塞。

答案 2 :(得分:1)

  

available()保持返回0,尽管流中有可读数据

如果available()返回零,则:

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

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

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

      

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

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

    只需在各种表现形式中阅读,阻止并对EOS做出正确反应。