Android Чтение из входного потока эффективно

В Windows вам нужен модуль msvcrt, в частности, похоже, что вы описываете свою проблему, функция msvcrt.getch :

Читать нажмите клавишу и верните полученный символ. На консоль ничего не отозвалось. Этот вызов будет блокироваться, если нажатие клавиши еще не доступно, но не будет ждать нажатия Enter.

blockquote>

(и т. Д. - см. Документы, на которые я только что указал). Для Unix см., Например, этот рецепт для простого способа построения аналогичной функции getch (см. также несколько альтернатив & amp; c в потоке комментариев этого рецепта).

144
задан Nikhil 26 June 2012 в 08:31
поделиться

5 ответов

Проблема вашего кода в том, что он создает множество тяжелых 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 , просто добавьте:

String result = total.toString ();

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

  • a + = b (или a = a + b ), где a и b - строки, копирует содержимое как a , так и b в новый объект (обратите внимание, что вы также копируете a , который содержит накопленную String ), и вы делаете эти копии на каждой итерации.
  • a.append (b) , где a - это StringBuilder , напрямую добавляет содержимое b в a , поэтому вы не копируете накопленную строку на каждой итерации.
343
ответ дан 23 November 2019 в 22:41
поделиться

Если файл длинный, вы можете оптимизировать свой код, добавив его к StringBuilder вместо использования конкатенации строк для каждой строки.

1
ответ дан 23 November 2019 в 22:41
поделиться

Может лучше, чем читать «по одной строке за раз» и соединять строки, попробовать «прочитать все доступные», чтобы избежать сканирования до конца строки , а также избежать объединения строк.

т.е. InputStream.available () и InputStream.read (byte [] b), смещение int, длина int)

3
ответ дан 23 November 2019 в 22:41
поделиться

Как насчет этого. Кажется, производительность выше.

byte[] bytes = new byte[1000];

StringBuilder x = new StringBuilder();

int numRead = 0;
while ((numRead = is.read(bytes)) >= 0) {
    x.append(new String(bytes, 0, numRead));
}

Редактировать: На самом деле это как бы охватывает и steelbytes, и Мориса Перри

6
ответ дан 23 November 2019 в 22:41
поделиться

Вы пробовали встроенный метод для преобразования потока в строку? Это часть библиотеки 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

33
ответ дан 23 November 2019 в 22:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: