我试图在没有定义字节数的情况下读取SocketChannel上的流。
我想到的替代解决方案是将预定义大小的不同ByteBuffers存储到一个列表中,这将允许我之后分配一个接收大小的新ByteBuffer并将结果放入其中。
问题是我处于阻塞模式并且找不到有效条件离开我在read方法上做的循环检查代码:
public static final Charset charsetUTF8 = Charset.forName("UTF-8");
public static final int BUFFER_SIZE = 1024;
public static String getUnbounded(String st, SocketAddress address) throws IOException {
SocketChannel sc = SocketChannel.open(address);
sc.write(charsetUTF8.encode(st));
List<ByteBuffer> listBuffers = new ArrayList<>();
ByteBuffer buff = ByteBuffer.allocate(BUFFER_SIZE);
while( sc.read(buff) > -1){
if(buff.remaining() == 0){
listBuffers.add(buff);
buff.clear();
}
}
listBuffers.add(buff);
ByteBuffer finalBuffer = ByteBuffer.allocate(BUFFER_SIZE * listBuffers.size());
for(ByteBuffer tempBuff: listBuffers){
finalBuffer.put(tempBuff);
tempBuff.clear();
}
finalBuffer.flip();
return charsetUTF8.decode(finalBuffer).toString();
}
关于如何解决这个问题的任何想法?
答案 0 :(得分:2)
你不能只是clear()
字节缓冲区。你需要分配一个新的;否则,相同的缓冲区将重复添加到listBuffers
。
ByteBuffer buff = ByteBuffer.allocate(BUFFER_SIZE);
while( sc.read(buff) > -1){
if(buff.remaining() == 0){
listBuffers.add(buff);
buff = ByteBuffer.allocate(BUFFER_SIZE);
}
}
if (buff.position() > 0) {
listBuffers.add(buff);
}
由于最后一个缓冲区可能(可能不会)已满,因此您应该考虑到这一点来计算finalBuffer
大小。
答案 1 :(得分:0)
HTTP响应流中的字节数不是“未定义”。请参阅RFC。它由以下任一定义:
必须以其中一种方式定义它,并且可能还有其他方式,以便HTTP持久连接可以工作,在此之后可能会有另一个响应。
我想知道为什么你实现这个,当HttpURLConnection
类已经存在时,以及各种第三方HTTP客户端,它们已经正确地实现了所有这些,还有很多其他的东西。< / p>
答案 2 :(得分:-1)
解决方案是离开循环我不得不打电话:
sc.shutdownOutput();
关闭写入流而不关闭读取流并将sc.read(buff)设置为-1