Чтение JSON для объекта: java.lang.OutOfMemoryError: пространство кучи Java - PullRequest
0 голосов
/ 18 февраля 2019

У меня есть JSON, подобный этому:

{
field1: "asd",
theBigField: "bigggg300mb",
field2: "tyu"
}

У меня есть входной параметр метода InputStream.Я не могу увеличить память на JVM, чтобы она приняла сообщение.Я также не могу сделать return new ObjectMapper().readValue(bytes, MyModel.class), так как у меня не так много памяти, чтобы создать объект из этого сообщения.Что я хотел бы сделать, это извлечь field1 и field2 из сообщения и проверить их на соответствие некоторым правилам.

И у меня есть InputStream при запуске метода .. Из него я получил байтовый массив .. Как я могу извлечь field1 и field2?

Я использую Java8, я могу использоватьпопулярные библиотеки с открытым исходным кодом и легкие библиотеки.Может быть, это можно сделать другим способом, программным путем?

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

1 Ответ

0 голосов
/ 18 февраля 2019

Моя первая попытка будет пометить MyClass::theBigField с помощью @JsonIgnore (если вы используете Jackson / ObjectMapper).Однако не уверен, что это сработает.

В крайнем случае, если структура ввода фиксирована и вы знаете это заранее, вы можете попытаться проанализировать поток вручную.Примерно так:

    private static void parseMyJson(InputStream stream) throws IOException {
          StringBuffer[] fields = new StringBuffer[] { new StringBuffer(), null, new StringBuffer() };
          int fieldNum = 0;
          boolean readingFieldValue = false;
          int read = 0;
          while ((read = stream.read()) != -1) {
            char readChar = (char) read;
            if (readChar == '"') {
               fieldNum += readingFieldValue ? 0 : 1;
               readingFieldValue = !readingFieldValue;
            } else if (readingFieldValue && fieldNum != 2) {
               fields[fieldNum-1].append(readChar);
            }
          }
          System.out.println(fields[0].toString());
          System.out.println(fields[2].toString());
    }

Приведенный выше код является очень примитивным и неэффективным синтаксическим анализатором (вам, вероятно, понадобится что-то более продвинутое), но дело в том, что вы выделяете в памяти только часть прочитанных символов, а затем отбрасываетеих, если они не соответствуют интересующим вас полям.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...