在我的应用中,我需要下载一些网页。我是这样做的
URL url = new URL(myUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(5000000);//5 seconds to download
conn.setConnectTimeout(5000000);//5 seconds to connect
conn.setRequestMethod("GET");
conn.setDoInput(true);
conn.connect();
int response = conn.getResponseCode();
is = conn.getInputStream();
String s = readIt(is, len);
System.out.println("got: " + s);
我的readIt
功能是:
public String readIt(InputStream stream) throws IOException {
int len = 10000;
Reader reader;
reader = new InputStreamReader(stream, "UTF-8");
char[] buffer = new char[len];
reader.read(buffer);
return new String(buffer);
}
问题在于它不会下载整个页面。例如,如果myUrl
为“https://wikipedia.org”,则输出为
如何下载整个页面?
更新
这里的第二个答案Read/convert an InputStream to a String解决了我的问题。问题出在readIt
函数中。您应该阅读来自InputStream
的回复:
static String convertStreamToString(java.io.InputStream is) {
java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
}
答案 0 :(得分:4)
您的代码存在许多错误:
您正在阅读具有固定大小的字符缓冲区。
您忽略了read(char[])
方法的结果。它返回实际读取的字符数......然后你需要使用它。
您假设read(char[])
将读取所有数据。实际上,它只能保证返回至少一个字符...或零以表示您已到达流的末尾。当您从网络连接到达时,您只能获取已由另一端发送并在本地缓冲的数据。
从char[]
创建字符串时,假设字符数组中的每个位置都包含流中的字符。
有多种方法可以正确完成,这是一种方式:
public String readIt(InputStream stream) throws IOException {
Reader reader = new InputStreamReader(stream, "UTF-8");
char[] buffer = new char[4096];
StringBuilder builder = new StringBuilder();
int len;
while ((len = reader.read(buffer) > 0) {
builder.append(buffer, 0, len);
}
return builder.toString();
}
另一种方法是使用readFully(Reader)
方法查找现有的第三方库方法。
答案 1 :(得分:0)
您需要在循环中读取,直到InputStream中没有剩余字节。
while (-1 != (len = in.read(buffer))) { //do stuff here}
答案 2 :(得分:0)
您只从输入流中读取10000个字节。
使用BufferedReader
让您的生活更轻松。
public String readIt(InputStream stream) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
StringBuilder out = new StringBuilder();
String newLine = System.getProperty("line.separator");
String line;
while ((line = reader.readLine()) != null) {
out.append(line);
out.append(newLine);
}
return out.toString();
}