Как читать JSON с разделителями строк из большого файла (строка за строкой)

Я пытаюсь загрузить большой файл (размером 2 ГБ), заполненный строками JSON, ограниченный символами новой строки. Пример:

{
    "key11": value11,
    "key12": value12,
}
{
    "key21": value21,
    "key22": value22,
}
…

Теперь я импортирую его:

content = open(file_path, "r").read() 
j_content = json.loads("[" + content.replace("}\n{", "},\n{") + "]")

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

Есть ли лучший способ указать разделитель JSON (newline \n вместо запятой ,)?

Кроме того, Python не может правильно отображать память для объекта, построенного из 2 ГБ данных, есть ли способ построить каждый объект JSON, поскольку я читаю файл по строкам? Спасибо!

Ответ 1

Просто прочитайте каждую строку и создайте объект json в это время:

with open(file_path) as f:
    for line in f:
        j_content = json.loads(line)

Таким образом, вы загружаете правильный полный json-объект (если нет значения \n в значении json где-то или в середине вашего json-объекта), и вы избегаете проблемы с памятью, поскольку каждый объект создается, когда это необходимо.

Существует также этот ответ.:

fooobar.com/questions/77184/...

Ответ 2

contents = open(file_path, "r").read() 
data = [json.loads(str(item)) for item in contents.strip().split('\n')]

Ответ 3

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

{
    "key11": 11,
    "key12": 12
}
{
    "key21": 21,
    "key22": 22
}

Просто читайте строки за строкой и создавайте блоки JSON по ходу:

with open(args.infile, 'r') as infile:

    # Variable for building our JSON block
    json_block = []

    for line in infile:

        # Add the line to our JSON block
        json_block.append(line)

        # Check whether we closed our JSON block
        if line.startswith('}'):

            # Do something with the JSON dictionary
            json_dict = json.loads(''.join(json_block))
            print(json_dict)

            # Start a new block
            json_block = []

Если вам интересно разобрать один очень большой файл JSON без сохранения всего в памяти, вы должны посмотреть на использование методов обратного вызова object_hook или object_pairs_hook в json.load API.

Ответ 4

Просто прочитайте это построчно и проанализируйте поток хотя ваш хакерский трюк (добавление запятых между каждой строкой JSON, а также начальная и конечная квадратные скобки, чтобы сделать его правильным списком) не благоприятен для памяти, если размер файла превышает 1 ГБ, поскольку весь контент попадет в ОЗУ.