我正在尝试从网站读取所有字节,但我认为我没有获得所有字节。我为字节数组长度提供了一个很高的值。 我使用了此方法,但它总是返回异常。
这是代码:
DataInputStream dis = new DataInputStream(s2.getInputStream());
byte[] bytes = new byte[900000];
// Read in the bytes
int offset = 0;
int numRead = 0;
while (offset < bytes.length
&& (numRead=dis.read(bytes, offset, bytes.length-offset)) >= 0) {
offset += numRead;
}
// Ensure all the bytes have been read in
if (offset < bytes.length) {
throw new IOException("Could not completely read website");
}
out.write(bytes);
编辑版本:
ByteArrayOutputStream bais = new ByteArrayOutputStream();
InputStream is = null;
try {
is = s2.getInputStream();
byte[] byteChunk = new byte[4096]; // Or whatever size you want to read in at a time.
int n;
while ( (n = is.read(byteChunk)) > 0 ) {
bais.write(byteChunk, 0, n);
}
}
catch (IOException e) {
System.err.printf ("Failed while reading bytes");
e.printStackTrace ();
// Perform any other exception handling that's appropriate.
}
finally {
if (is != null) { is.close(); }
}
byte[] asd = bais.toByteArray();
out.write(asd);
这是问题所在:
if (offset < bytes.length)
仅当原始数据超过 900,000 字节时,才会触发该命令。如果响应完全完成的时间少于此值,read()
将正确返回 -1 以指示流的结束。
如果offset
等于 bytes.length
,您实际上应该抛出异常,因为这表明您可能已截断数据:)
目前还不清楚你从哪里得到900,000的价值,请注意......
我建议,如果你想坚持使用原始流,你可以使用 Guava 的 ByteStreams.toByteArray
方法来读取所有数据。或者,您可以继续循环,读取到较小的缓冲区中,在每次迭代时写入ByteArrayOutputStream
。
我意识到这并不能回答您的具体问题。但是,当 HttpClient 等库存在并经过调试/分析等时,我真的不会手动编写这种东西。
例如,这里是如何使用流畅的界面
Request.Get("http://targethost/homepage").execute().returnContent();
JSoup 是一种替代方法,如果您正在处理抓取和抓取 HTML。