我在客户端有这个代码:
DataInputStream dis = new DataInputStream(socketChannel.socket().getInputStream());
while(dis.available()){
SomeOtherClass.method(dis);
}
但是available()
会一直返回0
,尽管流中有可读数据。因此,在完成要读取的实际数据之后,将空数据传递给另一个要读取的类,这会导致损坏。
经过一番搜索;我发现使用套接字时available()
不可靠,我应该从流中读取前几个字节,以实际查看数据是否可用于解析。
但在我的情况下;我必须将我从套接字获得的DataInputStream
引用传递给其他一些我无法更改的类。
是否可以从DataInputStream
读取几个字节而不会破坏它或任何其他建议?
答案 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()
返回零,则:
您使用的输入流不支持available()
,因此它只返回零。这不是这里的情况,因为您使用直接包裹在套接字输入流中的DataInputStream
,并且该配置支持available()
,或者......
流中没有可读数据。这似乎就是这种情况。实际上,您可以知道流中可读数据的唯一可能方式是调用available()
并获得肯定结果。没有其他说法。
availabe()
几乎没有正确用法,这不是其中之一。为什么你应该因为套接字接收缓冲区中没有任何数据而退出该循环?你应该摆脱这种循环的唯一方法是获得流结束条件。
我应该从流中读取前几个字节,以实际查看数据是否可用于解析。
这甚至没有意义。如果您可以从流中读取任何内容,则可以获得数据,如果不能,则不会。
只需在各种表现形式中阅读,阻止并对EOS做出正确反应。