Android

Android Reading from an Input stream efficiently

Эффективное чтение Android из входного потока

Я отправляю HTTP get-запрос на веб-сайт для приложения для Android, которое я создаю.

Я использую DefaultHttpClient и использую HttpGet для отправки запроса. Я получаю ответ сущности и из этого получаю объект InputStream для получения html страницы.

Затем я циклически просматриваю ответ, выполняя следующие действия:

BufferedReader r = new BufferedReader(new InputStreamReader(inputStream));
String x = "";
x = r.readLine();
String total = "";

while(x!= null){
total += x;
x = r.readLine();
}

Однако это ужасно медленно.

Это неэффективно? Я не загружаю большую веб-страницу - www.cokezone.co.uk поэтому размер файла невелик. Есть ли лучший способ сделать это?

Спасибо

Энди

Переведено автоматически
Ответ 1

Проблема вашего кода в том, что он создает множество тяжелых String объектов, копирует их содержимое и выполняет операции над ними. Вместо этого вам следует использовать StringBuilder чтобы избежать создания новых String объектов при каждом добавлении и избежать копирования массивов символов. Реализация для вашего случая будет примерно такой:

BufferedReader r = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder total = new StringBuilder();
for (String line; (line = r.readLine()) != null; ) {
total.append(line).append('\n');
}

Теперь вы можете использовать total без преобразования в String, но если вам нужен результат в виде String, просто добавьте:

Результат строки = total.toString();

Я постараюсь объяснить это лучше...


  • a += b (or a = a + b), где a и b являются строками, копирует содержимое обоих a и ba в новый объект (обратите внимание, что вы также копируете , который содержит Stringнакопленные данные, и вы делаете эти копии на каждой итерации.

  • a.append(b), где a - это StringBuilder, напрямую добавляет b содержимое к a, поэтому вы не копируете накопленную строку на каждой итерации.

Ответ 2

Вы пробовали встроенный метод преобразования потока в строку? Это часть библиотеки Apache Commons (org.apache.commons.io.IOUtils).

Тогда ваш код будет состоять из одной строки:

String total = IOUtils.toString(inputStream);

Документацию по нему можно найти здесь:
http://commons.apache.org/io/api-1.4/org/apache/commons/io/IOUtils.html#toString%28java.io.InputStream%29

Библиотеку ввода-вывода Apache Commons можно загрузить отсюда: http://commons.apache.org/io/download_io.cgi

Ответ 3

Another possibility with Guava:

dependency: compile 'com.google.guava:guava:11.0.2'

import com.google.common.io.ByteStreams;
...

String total = new String(ByteStreams.toByteArray(inputStream ));
Ответ 4

I believe this is efficient enough... To get a String from an InputStream, I'd call the following method:

public static String getStringFromInputStream(InputStream stream) throws IOException
{
int n = 0;
char[] buffer = new char[1024 * 4];
InputStreamReader reader = new InputStreamReader(stream, "UTF8");
StringWriter writer = new StringWriter();
while (-1 != (n = reader.read(buffer))) writer.write(buffer, 0, n);
return writer.toString();
}

I always use UTF-8. You could, of course, set charset as an argument, besides InputStream.

2023-05-19 16:40 java android