0
点赞
收藏
分享

微信扫一扫

Python_大容量json读入方式

君之言之 2022-01-28 阅读 74

其实原理很简单,打开一个文件会获得一个文件指针,然后以字节的方式读取每个json格式的 字节位置。然后存入到一个数组中,理论上来讲因为存储的只是每个json格式的字符串的 字节位置,那么将大大的节省空间

一、 创建一个Py脚本,里面有一个类

from msilib.schema import Class
import ujson
import re
import time
from turtle import st
class BIG_JSON(object):
def __init__(self):
pass
def index_fp(self,path=None):
if path==None:
return [None,"路径为空!"]
# path = "user_study.json"
fp_data = []
with open(path, "rb") as fp:
data = fp.read(1)
while data != b"":
off = 0
if data == b"{":
start = fp.tell()
while data != b"}" and data!=b"":
data = fp.read(1)
off = 1
if off == 1:
end = fp.tell()
fp.seek(end, 0)
fp_data.append([start, end-start])
off = 0
if data==b"":
return [None,"数据格式不正确,请检查!"]
data = fp.read(1)
return fp_data
def b_read(self,path=None,array=None):
if path==None:
return [None,"路径为空!"]
if array==None:
return [None,"数据为空!"]
with open(path, "rb") as fp:
# 设置文件指针位置
receive=fp.seek(array[0]-1,0)
# 读取大小
receive=fp.read(array[1]+1)
# receive=ujson.loads(z)
return receive

对于格式错误的json文本,将会终止并返回一个数组,数组[0]为None,数组[1]为错误原因

1. 错误的json格式

最后少了一个 }

{"minutes": 30, "created_at": "2016-05-01 00:00:10", "user_id": 199071, "lab": "\u7528\u6237\u53ca\u6587\u4ef6\u6743\u9650\u7ba1\u7406", "course": "Linux \u57fa\u7840\u5165\u95e8\uff08\u65b0\u7248\uff09"}, {"minutes": 6, "created_at": "2016-05-01 00:00:15", "user_id": 199373, "lab": "Linux \u7cfb\u7edf\u7b80\u4ecb", "course": "Linux \u57fa\u7840\u5165\u95e8\uff08\u65b0\u7248\uff09"}, {"minutes": 3, "created_at": "2016-05-01 00:01:49", "user_id": 173927, "lab": "Linux \u7cfb\u7edf\u7b80\u4ecb", "course": "Linux \u57fa\u7840\u5165\u95e8\uff08\u65b0\u7248\uff09"

2. 一个比较大的json文本

体积比较大,有16.3M。里面应该有92953条json格式的数据

​​蓝奏云下载地址:​​

​​https://wwi.lanzouq.com/iHKWCzbwn3e​​



二、 我使用 main.py 来进行测试

from PySide2 import os, sys
import big
import sys
big_json=big.BIG_JSON()
path = "demo.json"
fp_data=big_json.index_fp(path)
if len(fp_data)!=2 and fp_data[0]!=None:
print(len(fp_data))
sum=0
# 对数组中的数组进行累加
for i in fp_data:
sum+=sys.getsizeof(i)
print(len(fp_data),sum/1024/1024,sys.getsizeof(fp_data)/1024/1024)
else:
print(fp_data[1])

Python_大容量json读入方式_python

1. 我使用的是笔记本,建立一个索引大概需要10s。

2. 在这里我使用了 sys 模块中的 getsizeof方法进行大小统计,鉴于其不能统计嵌套数组的大小,所以我使用了for循环进行了累加,最后的大小应该是6.38+0.76=7.16M

1. 我进行了单独的测试,证明 getsizeof方法 真的不能统计嵌套数组的大小

Python_大容量json读入方式_python_02

三、 大结局

这玩意也不知道还有没有优化的余地,本来是想节省空间的,结果16M的文件,一顿操作后成功变成了7M。

每到这时候就想起了 c语言的好

1. 如果要读取也很简单

import json
import big
path = "user_study.json"
big_json=big.BIG_JSON()
# 建立索引
fp_data=big_json.index_fp(path)
# 获取内容
receive=big_json.b_read(path,fp_data[0])
# 编码
receive=receive.decode("utf-8")
# 把字符串转换成json,如果可以,用ujson,速度更快
receive=json.loads(receive)
print(receive)


举报

相关推荐

0 条评论