Mik*_*e S 6 python unicode json utf-8
我正在尝试解码一个大的utf-8 json文件(2.2 GB).我这样加载文件:
f = codecs.open('output.json', encoding='utf-8')
data = f.read()
Run Code Online (Sandbox Code Playgroud)
如果我尝试做任何:json.load,json.loads或者json.JSONDecoder().raw_decode我得到错误:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-40-fc2255017b19> in <module>()
----> 1 j = jd.decode(data)
/usr/lib/python2.7/json/decoder.pyc in decode(self, s, _w)
367 end = _w(s, end).end()
368 if end != len(s):
--> 369 raise ValueError(errmsg("Extra data", s, end, len(s)))
370 return obj
371
ValueError: Extra data: line 1 column -2065998994 - line 1 column 2228968302
(char -2065998994 - 2228968302)
Run Code Online (Sandbox Code Playgroud)
uname -m节目x86_64和
> python -c 'import sys;print("%x" % sys.maxsize, sys.maxsize > 2**32)'
('7fffffffffffffff', True)`
Run Code Online (Sandbox Code Playgroud)
所以我应该在64位,整数大小不应该是一个问题.
但是,如果我跑:
jd = json.JSONDecoder()
len(data) # 2228968302
j = jd.raw_decode(data)
j[1] # 2228968302
Run Code Online (Sandbox Code Playgroud)
返回的元组中的第二个值raw_decode是字符串的结尾,所以raw_decode似乎解析整个文件,最后似乎没有垃圾.
那么,我应该对json采取不同的做法吗?在raw_decode实际解码整个文件?为什么json.load(s)失败?
Tim*_*ers 10
我将其添加为注释,但注释中的格式化功能太有限了.
盯着源代码,
raise ValueError(errmsg("Extra data", s, end, len(s)))
Run Code Online (Sandbox Code Playgroud)
调用此函数:
def errmsg(msg, doc, pos, end=None):
...
fmt = '{0}: line {1} column {2} - line {3} column {4} (char {5} - {6})'
return fmt.format(msg, lineno, colno, endlineno, endcolno, pos, end)
Run Code Online (Sandbox Code Playgroud)
该(char {5} - {6})格式的一部分是你显示错误消息的这一部分:
(char -2065998994 - 2228968302)
Run Code Online (Sandbox Code Playgroud)
所以,在errmsg(),pos是-2065998994,end是2228968302.看哪!;-):
>>> pos = -2065998994
>>> end = 2228968302
>>> 2**32 + pos
2228968302L
>>> 2**32 + pos == end
True
Run Code Online (Sandbox Code Playgroud)
那就是,pos并且end"真的"是一样的.从errmsg()调用的地方返回,这意味着end并且len(s)实际上也是相同的 - 但是end被视为32位有符号整数. end反过来来自正则表达式匹配对象的end()方法.
所以这里的真正问题似乎是正则表达式引擎中的32位限制/假设.我鼓励你打开错误报告!
后来:回答你的问题,是的,raw_decode()正在解码整个文件.其他方法调用 raw_decode(),但之后添加(失败!)健全性检查.
| 归档时间: |
|
| 查看次数: |
285 次 |
| 最近记录: |