其实原理很简单,打开一个文件会获得一个文件指针,然后以字节的方式读取每个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])
1. 我使用的是笔记本,建立一个索引大概需要10s。
2. 在这里我使用了 sys 模块中的 getsizeof方法进行大小统计,鉴于其不能统计嵌套数组的大小,所以我使用了for循环进行了累加,最后的大小应该是6.38+0.76=7.16M
1. 我进行了单独的测试,证明 getsizeof方法 真的不能统计嵌套数组的大小

三、 大结局
这玩意也不知道还有没有优化的余地,本来是想节省空间的,结果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)









