Поскольку вы хотите, чтобы только последний объект JSON был удален из файла, гораздо более эффективный метод будет заключаться в том, чтобы определить первый действительный объект JSON в конце файла и обрезать файл, откуда расположена предыдущая запятая этого объекта JSON.
Это может быть достигнуто путем поиска и чтения назад от конца файла, одного относительно небольшого фрагмента за раз, разделения буфера на {
(так как он отмечает начало объекта JSON), ипоочередно вставляйте фрагменты в буфер до тех пор, пока буфер не будет разбираться как объект JSON (это делает код способным обрабатывать вложенные структуры dict), после чего вы должны найти предыдущую запятую из предыдущего фрагмента и добавить запятую кбуфер, так что, наконец, вы можете найти файл в том месте, где начинается буфер, и обрезать файл:
import json
chunk_size = 1024
with open('file.txt', 'rb+') as f:
f.seek(-chunk_size, 2)
buffer = ''
while True:
fragments = f.read(chunk_size).decode().split('{')
f.seek(-chunk_size * 2, 1)
i = len(fragments)
for fragment in fragments[:0:-1]:
i -= 1
buffer = '{%s%s' % (fragment, buffer)
try:
json.loads(buffer)
break
except ValueError:
pass
else:
buffer = fragments[0] + buffer
continue
break
next_fragment = fragments[i - 1]
# if we don't have a comma in the preceding fragment and it is already the first
# fragment, we need to read backwards a little more
if i == 1 and ',' not in fragments[0]:
f.seek(-2, 1)
next_fragment = f.read(2).decode() + next_fragment
buffer = next_fragment[next_fragment.rindex(','):] + buffer
f.seek(-len(buffer.encode()), 2)
f.truncate()