2013-10-07 9 views
6

मैं एक बड़ी यूटीएफ -8 जेसन फ़ाइल (2.2 जीबी) को डीकोड करने की कोशिश कर रहा हूं। मैं तो जैसे फ़ाइल लोड:2.2 जीबी जेएसओएन फ़ाइल असंगत रूप से

f = codecs.open('output.json', encoding='utf-8') 
data = f.read() 

अगर मैं से कोई भी कार्य करने का प्रयास करें:

--------------------------------------------------------------------------- 
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) 


uname -m से पता चलता x86_64 और

: json.load, json.loads या json.JSONDecoder().raw_decode मैं त्रुटि मिलती है
> python -c 'import sys;print("%x" % sys.maxsize, sys.maxsize > 2**32)' 
('7fffffffffffffff', True)` 

तो मुझे 64 बिट पर होना चाहिए और पूर्णांक आकार एक समस्या नहीं होनी चाहिए।

हालांकि, अगर मैं चलाएँ:

jd = json.JSONDecoder() 
len(data) # 2228968302 
j = jd.raw_decode(data) 
j[1] # 2228968302 

टपल raw_decode द्वारा लौटाए में दूसरा मूल्य स्ट्रिंग के अंत है, इसलिए raw_decode पर मालूम होता है कोई कचरा के साथ पूरे फ़ाइल को पार्स करने लगता है समाप्त।

तो, क्या मुझे जेसन के साथ अलग-अलग कुछ करना चाहिए? raw_decode वास्तव में पूरी फ़ाइल को डीकोड कर रहा है? json.load(s) क्यों विफल रहा है?

+2

आप किस प्रकार की प्रणाली पर चल रहे हैं? 2।एक हस्ताक्षरित 32-बिट पूर्णांक के लिए 2 अरब बहुत बड़ा है, और अपवाद विवरण में नकारात्मक संख्याएं बताती हैं कि आप इसके साथ समस्याओं में भाग ले रहे हैं। –

+0

अंतर्निहित कोड को देखे बिना, मुझे लगता है कि फ़ंक्शन इनपुट को एक स्ट्रिंग में परिवर्तित करते हैं, और उनके पास उस आकार की स्ट्रिंग को संभालने का प्रयास करने वाले ओवरफ़्लो समस्याएं हैं। संभवतः "कच्चा" संस्करण नहीं है, और इस प्रकार पूरी चीज को पार्स करने में सक्षम है। – Gabe

+0

@TimPeters मैंने इसे अपने प्रश्न में जोड़ा लेकिन मैं 64 बिट आर्किटेक्चर पर हूं। –

उत्तर

9

मैं इसे एक टिप्पणी के रूप में जोड़ूंगा, लेकिन टिप्पणियों में स्वरूपण क्षमताओं बहुत सीमित हैं।

स्रोत कोड को घूर,

raise ValueError(errmsg("Extra data", s, end, len(s))) 

कॉल इस समारोह:

(char -2065998994 - 2228968302) 
:

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) 

प्रारूप का (char {5} - {6}) हिस्सा त्रुटि संदेश के इस हिस्से आप से पता चला है

तो, errmsg() में, pos है -2065998994 और end 2228 9 68302 है। देखो! ;-):

>>> pos = -2065998994 
>>> end = 2228968302 
>>> 2**32 + pos 
2228968302L 
>>> 2**32 + pos == end 
True 

यही है, pos और end हैं "वास्तव में" एक ही। errmsg() कहां से कहा गया था, इसका मतलब है कि end और len(s) वास्तव में वही हैं - लेकिन end को 32-बिट हस्ताक्षरित पूर्णांक के रूप में देखा जा रहा है। end बदले में नियमित अभिव्यक्ति मिलान ऑब्जेक्ट की end() विधि से आता है।

तो असली समस्या यहां regexp इंजन में 32-बिट सीमा/धारणा प्रतीत होती है। मैं आपको open a bug report पर प्रोत्साहित करता हूं!

बाद में: अपने प्रश्नों का उत्तर देने के लिए, हाँ, raw_decode() संपूर्ण फ़ाइल को डीकोड कर रहा है। अन्य विधियों कॉलraw_decode(), लेकिन बाद में (असफल!) सैनिटी चेक जोड़ें।

संबंधित मुद्दे