python-3.x - 在 Python 中擦除文本文件的一部分
问题描述
我的硬盘中有一个非常大的文本文件。它有大约 800 万个用逗号分隔的 json 文件,我想删除最后一个 json ;但是,因为它真的很大,我无法通过常规编辑器(Notepad++、Sublime、Visual Studio Code……)来完成。所以,我决定使用 Python,但我不知道如何使用 python 擦除现有文件的一部分。任何形式的帮助将不胜感激。
PS:我的文件有这样的结构:
json1, json2, json3, ...
when each json looks like {"a":"something", "b":"something", "c":"something"}
解决方案
由于您只希望从文件中删除最后一个 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()
推荐阅读
- python - 修改 dtypes 的输出
- javascript - Firebase 响应太慢
- python - 如何判断 Firestore 中刚刚添加了哪个文档?
- php - PDO 插入数组只显示一个条目
- c# - EF Core 一对多按导航属性(不是按主键)
- asp.net-core - 自定义授权属性不允许在 asp.net core 3 中授权
- tarantool - 如果我有两个,如何转移特定的辅助密钥?
- macos - 如何在 macOS 上停止\关闭\杀死 tcp 连接
- python - Pandas 结合了两种不同长度的时间序列数据框
- nopcommerce - 我想允许正斜杠进入 SENAME