我在客户端有这段代码:
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);
}
但请注意,此代码的行为将与可用示例不同(如果可用有效),因为可用不会阻止,但读取可能会阻止。
但是
available()
一直返回 0,尽管流中有可读数据
如果available()
返回零,则:
-
您使用的输入流不支持
available()
,因此它只返回零。这里的情况并非如此,因为您使用的是直接包裹在套接字输入流周围的DataInputStream
,并且该配置确实支持available()
、 或 ... -
流中没有可读数据。这里的情况似乎就是这样。事实上,在不实际读取数据的情况下知道流中有可读数据的唯一可能方法是调用
available()
并获得积极的结果。没有其他方法可以说。
availabe()
的正确用法很少,这不是其中之一。为什么仅仅因为套接字接收缓冲区中没有任何数据就脱离该循环?您应该摆脱该循环的唯一方法是获得流结束条件。
我应该从流中读取前几个字节,以实际查看数据是否可以解析。
这甚至没有意义。如果可以从流中读取任何内容,则有可用数据,如果不能,则没有数据。
只需阅读,阻止并正确响应EOS的各种表现形式。