python - 如何在 python 中使用 mmap 加载 json?(在窗户上)
问题描述
我有一个 json 文件,我使用 python 中的内存映射打开它。即使 json_file 不包含那么多字段,我也将大小设置为 1024。当我这样做时,json.loads(...)
我得到了Error: raise JSONDecodeError("Extra data", s, end)
. 我打开json文件,看到最后有NULL
字符。看这张图片:
我不确定加载 json 文件的正确方法。我打开 mmap 文件并加载 json 的代码如下。
The json file has contents shown below:
{
"Gardens": {
"Seaside": {
"@loc": "porch",
"@myID": "1.2.3",
"Tid": "1",
"InfoList": {
"status": {
"@default": "0",
"@myID": "26"
},
"count": {
"@default": "0",
"@myID": "1"
}
},
"BackYard": {
"@loc": "backyard",
"@myID": "75",
"Tid": "2",
"InfoList": {
"status": {
"@default": "6",
"@myID": "32"
},
"count": {
"@default": "0",
"@myID": "2"
}
}
}
}
}
} # There are NULL characters here as doing the mmap fills NULL characters as the size of the file provided is 1024
# Open and read file and MMAP (WRITE access)
json_file = open(json_path, "r+", encoding="utf-8")
mapped_file = mmap.mmap(json_file.fileno(), 1024, access=mmap.ACCESS_WRITE)
# Create the mmap file buffer
mappedFile.seek(0)
file_size = os.path.getsize(json_path)
buffer_for_json = mappedFile[:file_size]
# Content is JSON, so load it
json_data = json.loads(buffer_for_json.decode("utf-8")) # ERROR: raise JSONDecodeError("Extra data", s, end)
我真的很迷茫,不知道如何解决这个问题。任何帮助,将不胜感激。:)
解决方案
我无法对此进行测试,因为我没有 Windows 来测试 Windows 版本mmap.mmap
,但我认为这正在发生:
当您mmap.mmap()
使用大于文件大小的长度值调用时,磁盘上的原始文件会被更改。文档说:
如果length大于文件的当前大小,则将文件扩展为包含length个字节。
最有可能的是,该文件用空字节填充到 1024 字节的大小(您指定的大小)。1024也是你os.path.getsize(json_path)
之后得到的。这就是为什么mappedFile[:file_size]
包含这些尾随空字节的原因。
我建议您有条件地设置 mmap 长度,例如:
json_file = open(json_path, "r+", encoding="utf-8")
length = min(1024, os.path.getsize(json_path))
mapped_file = mmap.mmap(json_file.fileno(), length, access=mmap.ACCESS_WRITE)
这应该避免空字节填充(顺便说一句,这也会永久损坏您的 JSON 文件)。
推荐阅读
- python - 将 Visual Studio 2017 中的 Anaconda 更新到最新版本
- linux - 如何退出“顶部”的“循环” | grep 用户?
- c# - GetConversationMembersAsync 返回 403(禁止)
- javascript - (node:17453) UnhandledPromiseRejectionWarning: MongoNetworkError: failed to connect to server [localhost:27017] on first connect
- typescript - 对类型脚本中严格类型检查的交叉类型的混淆
- javascript - 来自其他功能的 Google Script ui.button 调用提示
- python - Python - 如何在索引中使用字符串
- java - Nodejs cipher.setAAD(buffer) vs Java chiper.updateAAD(byte[]),我会得到相同的 authTag 吗?
- javascript - 我将如何在 jQuery 中重复或循环 img 选择器?
- mongodb - DynamoDB vs ElasticSearch vs S3 - 哪个服务用于超快速获取/放置 10-20MB 文件?