2013-02-13 15 views
18

मैं अजगर 2.7 में 800 जीबी एक्सएमएल फ़ाइल पढ़ रहा हूं और इसे एक एट्री इटेटिव पार्सर के साथ पार्स कर रहा हूं।पायथन में 800 जीबी एक्सएमएल फ़ाइल का कुशल पढ़ने 2.7

वर्तमान में, मैं केवल open('foo.txt') का उपयोग करके कोई बफरिंग तर्क नहीं कर रहा हूं। मैं थोड़ा उलझन में हूं कि क्या यह दृष्टिकोण मुझे लेना चाहिए या मुझे बफरिंग तर्क का उपयोग करना चाहिए या आईओ.बफर्डर रीडर या io.open या io.TextIOBase जैसे आईओ से कुछ उपयोग करना चाहिए।

सही दिशा में एक बिंदु की बहुत सराहना की जाएगी।

+22

800 जीबी पाठ फ़ाइल ?! भगवान की मां ... आप किस बिंदु पर कहना चाहते हैं कि डेटाबेस में चकना अच्छा विचार है? – Makoto

+8

@Makoto, बदतर शीर्षक पाठ कहते हैं, लेकिन शरीर यह _XML_ –

+5

मैं सिर्फ तुम्हारे लिए आशा है कि फ़ाइल वास्तव में मान्य XML है कहते हैं ... – poke

उत्तर

12

मानक open() function पहले से ही डिफ़ॉल्ट रूप से, एक बफर्ड फ़ाइल (यदि आपके प्लेटफ़ॉर्म पर उपलब्ध हो) लौटाता है। फ़ाइल ऑब्जेक्ट्स के लिए आमतौर पर पूरी तरह से buffered है।

आमतौर पर का अर्थ है कि पायथन इसे सी stdlib कार्यान्वयन के लिए छोड़ देता है; यह UTF-16 फ़ाइल नामों का समर्थन करने के लिए Windows पर fopen() call (wfopen()) का उपयोग करता है, जिसका अर्थ है कि फ़ाइल के लिए डिफ़ॉल्ट बफरिंग चुना जाता है; लिनक्स पर मेरा मानना ​​है कि 8kb होगा। एक्सएमएल जैसे शुद्ध-पढ़ने वाले ऑपरेशन के लिए इस प्रकार के बफरिंग को बिल्कुल जो आप चाहते हैं।

iterparse द्वारा किए गए एक्सएमएल पार्सिंग फ़ाइल को 16384 बाइट्स (16 केबी) के टुकड़ों में पढ़ता है।

open('foo.xml', buffering=(2<<16) + 8) # buffer enough for 8 full parser reads 

जो डिफ़ॉल्ट बफर आकार (जो मैं फ़ाइल ब्लॉक आकार या एक से अधिक उसके मैच के लिए उम्मीद थी) को पार कर जाएगी:

आप buffersize नियंत्रित करने के लिए चाहते हैं, buffering कीवर्ड तर्क का उपयोग करें। this article के अनुसार पढ़ने वाले बफर को सहायता में वृद्धि करना चाहिए, और आकार का उपयोग करके कम से कम 4 बार अपेक्षित पढ़ने वाले ब्लॉक आकार प्लस 8 बाइट्स पढ़ने के प्रदर्शन में सुधार करने जा रहे हैं। उपरोक्त उदाहरण में मैंने इसे ElementTree पढ़ने के आकार के 8 बार सेट कर दिया है।

io.open() function ऑब्जेक्ट्स की नई पायथन 3 आई/ओ संरचना का प्रतिनिधित्व करता है, जहां I/O को आपको अधिक लचीलापन देने के लिए कक्षा प्रकारों के एक नए पदानुक्रम में विभाजित किया गया है। कीमत अधिक संकेत है, डेटा के लिए यात्रा करने के लिए अधिक परतें हैं, और पाइथन सी कोड ओएस को छोड़ने के बजाए और अधिक काम करता है।

आप देख सकते हैं और देख सकते हैं कि io.open('foo.xml', 'rb', buffering=2<<16) कोई बेहतर प्रदर्शन करने जा रहा है या नहीं। rb मोड में खुलने से आपको io.BufferedReader instance मिल जाएगा।

आप io.TextIOWrapper का उपयोग करना चाहते हैं; अंतर्निहित एक्सपैट पार्सर कच्चे डेटा चाहता है क्योंकि यह आपके एक्सएमएल फ़ाइल एन्कोडिंग को डीकोड करेगा। यह केवल अतिरिक्त ओवरहेड जोड़ देगा; यदि आप r (टेक्स्टमोड) में इसके बजाय खोलते हैं तो आपको यह प्रकार मिलता है।

io.open() का उपयोग करके आप अधिक लचीलापन और एक अमीर एपीआई दे सकता है, लेकिन अंतर्निहित सी फ़ाइल वस्तु open() बजाय fopen(), का उपयोग कर खोला जाता है और सभी बफरिंग अजगर io.BufferedIOBase कार्यान्वयन द्वारा नियंत्रित किया जाता।

आपकी समस्या इस जानवर को संसाधित करेगी, फाइल नहीं पढ़ती, मुझे लगता है। एक 800 जीबी फ़ाइल पढ़ने के दौरान डिस्क कैश वैसे भी काफी शॉट होगा।

+0

क्या ElementTree वास्तव में काम करेगा? क्या यह पूरे पेड़ को स्मृति में रखने की कोशिश नहीं करेगा? – poke

+3

@poke: यही है * iterparse() '* के लिए * है। यह आपको ElementTree API के साथ ईवेंट-संचालित पार्सिंग देता है, ताकि आप आवश्यकतानुसार तत्वों को फिर से मुक्त कर सकें। –

+0

आह ठंडा, उसे नहीं पता था - धन्यवाद! – poke

1

क्या आपने आलसी कार्य करने की कोशिश की है?: Lazy Method for Reading Big File in Python?

ऐसा लगता है कि यह आपके प्रश्न का उत्तर दे रहा है। http://dev.mysql.com/downloads/ NoSQL भी नि: शुल्क है और एक छोटे से अधिक डेटा के 800GB लेखन, या इसी तरह की मात्रा को शामिल संचालन के अनुरूप हो सकता है,: http://www.oracle.com/technetwork/database/nosqldb/downloads/default-495311.html

+1

'iterparse()' * पहले से ही * खंडों में फ़ाइल को पढ़ता है। –

+0

सहमत हैं, पहिया को फिर से आविष्कार करने की कोई आवश्यकता नहीं है। मुझे लगता है कि वे पोस्ट में भी .iter() का उपयोग करते हैं। – RandomUs1r

1

हालांकि, मैं एक डेटाबेस के लिए अपने डेटा लिखने के लिए इस पद्धति का उपयोग करने पर विचार करेंगे, mysql नि: शुल्क है मैंने इस तरह की महाकाव्य एक्सएमएल फाइलों के साथ कोशिश नहीं की है, लेकिन पिछली बार मुझे बड़ी (और अपेक्षाकृत सरल) एक्सएमएल फाइलों से निपटना पड़ा, मैंने sax parser का उपयोग किया।

यह मूल रूप से आपको प्रत्येक "ईवेंट" के लिए कॉलबैक देता है और आपको आवश्यक डेटा स्टोर करने के लिए इसे छोड़ देता है। आप एक खुली फ़ाइल दे सकते हैं ताकि आपको इसे एक साथ में पढ़ने की आवश्यकता न हो।

+1

एलिमेंटट्री का 'iterparse() 'एक सैक्स पार्सर के शीर्ष पर बनाया गया है। –

+0

आह, जानना अच्छा है। – JCash

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