Подтвердить что ты не робот

Ошибка из памяти при помещении большого JSON (InputStream) в String

Я получаю gziped JSON из веб-службы, а затем я разархивирую его (размер unziped JSON составляет 3,2 МБ). Мне нужно преобразовать полученный InputStream в String, чтобы затем создать JSONObject и проанализировать его. Я делаю это с помощью этого кода:

public static String InputStreamToString(InputStream in) 
    throws IOException {

    BufferedInputStream bis = new BufferedInputStream(in);
    ByteArrayOutputStream buf = new ByteArrayOutputStream();
    int result = bis.read();

    while(result != -1) {
      byte b = (byte)result;
      buf.write(b);
      result = bis.read();
    }        
    return buf.toString();
}

Я получаю java.lang.OutOfMemoryError в последней строке: "return buf.toString();" на эмуляторе и устройстве с 288MB Ram.

Что мне делать?

4b9b3361

Ответ 1

Чтение в байте за один раз - это 1990-е. Или используйте HttpClient и BasicResponseHandler, или, по крайней мере, прочитайте данные в уважаемых фрагментах и добавьте их с помощью StringBuilder.

Предполагая, что у вас все еще проблема, проблема в том, что нет единого блока памяти, который достаточно велик для вашей строки, основываясь на других вещах, которые делает ваше приложение. Сборщик мусора Android не является сборщиком уплотнений, поэтому для определенного запроса на распределение может быть достаточно свободного места для кучи, но этого недостаточно.

В этом случае вам может потребоваться переключиться на какой-то потоковый JSON-парсер. Если вы планируете использовать только Honeycomb и выше, вы можете использовать JSONReader. В противном случае Jackson, как сообщается, работает на Android и, по-видимому, имеет режим потоковой передачи.

Ответ 2

Вы можете попытаться создать новый JSONObject, используя

new JSONObject(new JSONTokener(in)) 

вместо прямого преобразования в строку. Однако это, вероятно, только задержит проблему. Если у вас недостаточно памяти для загрузки 3,2-мегабитной строки в память, у вас, вероятно, не будет достаточно памяти для загрузки этого в качестве объекта json, который займет больше памяти, чем простая строка.