我想从java.net.URLConnection
读取前x个字节(虽然我不是被迫使用这个类 - 欢迎其他建议)。
我的代码如下所示:
val head = new Array[Byte](2000)
new BufferedInputStream(connection.getInputStream).read(head)
IOUtils.toString(new ByteArrayInputStream(head), charset)
它可以工作,但这段代码只加载来自网络的前2000个字节吗?
下一次试用
由于'JB Nizet'说使用缓冲输入流没用,所以我尝试使用InputStreamReader
:
val head = new Array[Char](2000)
new InputStreamReader(connection.getInputStream, charset).read(head)
new String(head)
此代码可能更好,但加载时间大致相同。那么这个程序是否限制了传输的字节?
答案 0 :(得分:7)
不,它没有。它最多可读取8192个字节(deault缓冲区大小为BufferedInputStream
)。它还可以读取0个字节或0到2000之间的任意数量的字节,因为您不检查实际已读取的字节数,以及read()
方法返回的字节数。
最后,根据charset的值以及HTTP响应使用的实际字符集,这可能会返回一个不正确的字符串,或者在多字节字符中间截断的字符串。您应该使用Reader来阅读文本。
我建议你阅读Java IO tutorial。
答案 1 :(得分:5)
您可以使用Apache Commons IO中的read(Reader, char[])
。只需将一个2000个字符的缓冲区传递给它,它将填充尽可能多的字符,最多2000个。
请务必了解其他答案/评论中的异议,特别是:
Buffered...
包装,这违背了你的意图。Reader
读取2000 字符而不是InputStream
读取2000 字节。正确的程序是从响应的标头(Content-Type
)确定字符编码,并将该编码设置为InputStreamReader
。read(char[])
上调用普通Reader
将无法完全填充您提供给它的数组。无论数组多大,它都只能读取一个字符!除此之外,我强烈建议您使用Apache HttpClient支持java.net.URLConnection
。它更加灵活。
修改:要了解Reader.read
和IOUtils.read
之间的区别,有必要检查后者的来源:
public static int read(Reader input, char[] buffer,
int offset, int length)
throws IOException
{
if (length < 0) {
throw new IllegalArgumentException("Length must not be negative: " + length);
}
int remaining = length;
while (remaining > 0) {
int location = length - remaining;
int count = input.read(buffer, offset + location, remaining);
if (EOF == count) { // EOF
break;
}
remaining -= count;
}
return length - remaining;
}
由于Reader.read
可以读取的字符少于给定长度(我们只知道它至少为1,最多只有长度),我们需要迭代调用它直到得到我们想要的数量。