Как мы можем перебирать файл JSON размером около 2 ГБ с помощью Java

Я читаю 3 значения столбца из базы данных (около 50 000 записей), а затем пытаюсь найти это значение в файле Json. Файл Json содержит 2 миллиона объектов Json. Я пробовал следующие подходы.

Подход 1.

JSONArray json = readJson(Constants.jsonFilePath);

private JSONArray readJson(String jsonFilePath) {
    String content = null;
    File file = new File(Constants.jsonFilePath);
    try {
        content = FileUtils.readFileToString(file, "utf-8");
    } catch (IOException e) {
        e.printStackTrace();
    }
    return new JSONArray(content);

}

А затем линейно ищем нужное значение поля

Я протестировал приведенный выше код для файла размером 150 МБ, и он работал очень хорошо. Но когда я тестировал его для файла размером 2 ГБ, я получаю ошибку OutOfHeapMemory.

Подход 2:

Затем я попытался прочитать из файла 100 000 объектов Json за раз, а затем проверить требуемое значение поля, но процесс очень медленный.

Я использую библиотеку org.json. Есть ли лучший способ решить указанную выше проблему?

Это действительно будет непростой процесс. Объясняя вашу потребность, другие люди могут предложить другие альтернативы.

Paulo Henrique 30.07.2018 15:17

Sachin - см. Мой комментарий к ответу jwenting. Кроме того, лакхи - это единица измерения, малоизвестная за пределами Индии.

J E Carter II 30.07.2018 15:21
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
3
2
715
3

Ответы 3

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

Конечно, вы можете указать JVM потребовать 4 ГБ ОЗУ и надеяться, что этого будет достаточно, но для обработки такого количества данных все равно потребуется немало времени.

Возникает вопрос, почему вы вообще пытаетесь обрабатывать такой большой отдельный объект JSON, есть гораздо лучшие способы хранения больших объемов данных, чем те, которые требуют гораздо меньше ресурсов ЦП и ОЗУ для обработки. На ум приходят базы данных, удобные для поиска с использованием SQL или подобных языков запросов.

На этом этапе вы работаете не только с пределами того, что можно разумно ожидать от JVM, но и с самой операционной системой.

+1 за неправильный формат для этого количества данных. csv, денормализованный до плоской структуры, будет обрабатываться намного быстрее. Рассмотрите возможность использования посредника перед созданием json рядом с источником данных.

J E Carter II 30.07.2018 15:18

Вам следует использовать потоковый парсер JSON, а не читать файл целиком. Это будет медленным, но управляемым. Посмотрите на API потоковой передачи Джексона, чтобы узнать, как этого добиться.

Это означает, что вам придется обрабатывать низкоуровневую обработку объектов JSON, но это должно быть быстрее, чем загрузка всего JSON в память.

Вот ссылка на сайт для использования Streaming API.

Обратите внимание, что GSON также имеет аналогичный потоковый API.

Вы пробовали создать свой собственный парсер JSON (для конкретного объекта JSON)? Поскольку в этом случае вы знаете формат JSON. Затем просто линейно проанализируйте один объект obj (вы можете использовать readLine () до тех пор, пока '}' не закроется для первого открытого '{') и сравните со значениями поиска. : D Вы также можете сократить время с помощью многопоточного подхода.

Это всего лишь идея, и я до сих пор не знаю, как выглядит ваш файл JSON.

Другие вопросы по теме