2015-12-16 6 views
3

В моем приложении мне нужно загрузить некоторую веб-страницу. Я делаю это так, как этотURLConnection не читает целую страницу

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

Возможно, сделать время чтения дольше? – lonesome

+0

@lonesome выглядит так, как будто я нашел решение здесь: https://stackoverflow.com/questions/309424/read-convert-an-inputstream-to-a-string – PepeHands

+0

@lonesome readInt от 'developer.android.com' работает странный. Если я прочитаю, используя этот трюк 'java.util.Scanner s = new java.util.Scanner (is) .useDelimiter (" \\ A "); return s.hasNext()? s.next(): ""; 'тогда все нормально – PepeHands

ответ

0

Вы должны прочитать в цикле, пока нет больше байт, оставшихся в InputStream.

while (-1 != (len = in.read(buffer))) { //do stuff here} 
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(); 
} 
+0

, но ответ короче 10000 байт – PepeHands

+0

Но, возможно, вы правы. чтение, как и во втором aswer здесь, решило проблему https://stackoverflow.com/questions/309424/read-convert-an-inputstream-to-a-string – PepeHands

+0

также у меня был тот же результат, тогда 'len' был 1000 – PepeHands

4

Есть ряд ошибок код:

  1. Вы читаете в символьный буфер с фиксированным размером.

  2. Вы игнорируете результат метода read(char[]). Он возвращает количество фактически прочитанных символов ... и вам нужно использовать это.

  3. Вы считаете, что read(char[]) будет читать все данные. Фактически, гарантируется возврат хотя бы одного символа ... или нуля, чтобы указать, что вы достигли конца потока. Когда вы достигаете сетевого подключения, вы можете получить только данные, которые уже были отправлены другим концом, и буферизированы локально.

  4. При создании строки из 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).

+0

Спасибо за пояснения. Эта функция 'readIt', которую я только что скопировал: https://developer.android.com/intl/ru/training/basics/network-ops/connecting.html Ваше решение дает мне исключение ArrayIndexOutOfBounds, даже если я установите размер буфера до 10000 (загружаемая страница составляет всего 5 КБ). Я думаю, что самый простой способ решить это в моей ** Обновление ** раздел – PepeHands

+0

Я вижу ошибку: исправил ее. –

Смежные вопросы