2009-07-17 16 views
8

मेरे पास एक बड़ी एक्सएमएल फ़ाइल (40 जीबी) है जिसे मुझे छोटे हिस्सों में विभाजित करने की आवश्यकता है। मैं सीमित स्थान के साथ काम कर रहा हूं, इसलिए मूल फ़ाइल से लाइनों को हटाने का कोई तरीका है क्योंकि मैं उन्हें नई फाइलों में लिखता हूं?जगह में पाइथन फ़ाइल बदलें

धन्यवाद!

+0

क्षमा करें, मैं इसके बारे में क्या है नहीं मिलता है । –

+1

अगर मैं गलत हूं तो मुझे सही करें, लेकिन वह छोटी भागों में एक बहुत बड़ी फ़ाइल को विभाजित करने की कोशिश कर रहा है। हालांकि, चूंकि फ़ाइल इतनी बड़ी है, क्योंकि वह विभाजन बनाता है, उसे अंतरिक्ष को बचाने के लिए मूल फ़ाइल से उस हिस्से को हटाना होगा। –

+0

@ जेसे - यह सही है। – AlbertoPL

उत्तर

7

तो बस फ़ाइल के पीछे से पढ़ना शुरू आप एन टुकड़ों में फ़ाइल को विभाजित करना चाहते कहो, (कम या ज्यादा) और बार-बार फोन truncate:

फ़ाइल के आकार छोटा करें। यदि वैकल्पिक आकार तर्क मौजूद है, तो फ़ाइल उस आकार (सबसे अधिक) को छोटा कर दिया जाता है। आकार वर्तमान स्थिति के लिए डिफ़ॉल्ट है। वर्तमान फ़ाइल स्थिति बदल नहीं है। ...

import os 
import stat 

BUF_SIZE = 4096 
size = os.stat("large_file")[stat.ST_SIZE] 
chunk_size = size // N 
# or simply set a fixed chunk size based on your free disk space 
c = 0 

in_ = open("large_file", "r+") 

while size > 0: 
    in_.seek(-min(size, chunk_size), 2) 
    # now you have to find a safe place to split the file at somehow 
    # just read forward until you found one 
    ... 
    old_pos = in_.tell() 
    with open("small_chunk%2d" % (c,), "w") as out: 
     b = in_.read(BUF_SIZE) 
     while len(b) > 0: 
      out.write(b) 
      b = in_.read(BUF_SIZE) 
    in_.truncate(old_pos) 
    size = old_pos 
    c += 1 

सावधान रहो के रूप में मैं इस के किसी भी परीक्षण नहीं किया। ट्रंकेट कॉल के बाद flush पर कॉल करने के लिए इसकी आवश्यकता हो सकती है, और मुझे नहीं पता कि फ़ाइल सिस्टम वास्तव में अंतरिक्ष को कितनी तेज़ कर देगा।

+0

सभी इनपुट के लिए धन्यवाद। मैं आज रात आपके कुछ सुझावों का प्रयास करूंगा। – Maulin

+2

उस के साथ शुभकामनाएं :) –

+0

अच्छी जानकारी। मैं अपने सिर के शीर्ष से इस तरह कुछ खींचने में सक्षम होने के लिए पर्याप्त पायथन नहीं करता हूं। – NoMoreZealots

1

मुझे यकीन है कि वहां है, क्योंकि मैं भी चलाने वाली स्क्रिप्ट की स्रोत फ़ाइलों से संपादित/पढ़ने में सक्षम हूं, लेकिन सबसे बड़ी समस्या शायद सभी स्थानांतरण हो जाएगी जो आपको किया जाएगा फ़ाइल की शुरुआत में शुरू किया। दूसरी तरफ, यदि आप फ़ाइल के माध्यम से जाते हैं और लाइनों की सभी शुरुआती स्थितियों को रिकॉर्ड करते हैं, तो आप लाइनों की प्रतिलिपि बनाने के लिए स्थिति के विपरीत क्रम में जा सकते हैं; एक बार ऐसा करने के बाद, आप वापस जा सकते हैं, नई फाइलें ले सकते हैं, एक समय में, और (यदि वे पर्याप्त छोटे हैं), सूची बनाने के लिए रीडलाइन() का उपयोग करें, सूची के क्रम को उलट दें, फिर शुरुआत की तलाश करें फ़ाइल के और अपने पुराने क्रम में लाइनों को उनके पुराने क्रम में लाइनों के साथ ओवरराइट करें।

(truncate() विधि का उपयोग करके आप अंत में लाइनों के पहले ब्लॉक को पढ़ने के बाद फ़ाइल को छोटा कर देंगे, जो फ़ाइल फ़ाइल ऑब्जेक्ट के अलावा किसी भी तर्क के बिना उपयोग की जाने वाली वर्तमान फ़ाइल स्थिति से पहले सभी डेटा को मिटा देता है, आपको लगता है कि ' अपनी फ़ाइल को पढ़ने के लिए io पैकेज से कक्षाओं में से किसी एक वर्ग या उप-वर्ग का उपयोग कर रहे हैं। आपको केवल यह सुनिश्चित करना होगा कि वर्तमान फ़ाइल स्थिति अंतिम पंक्ति की शुरुआत में समाप्त होने के लिए समाप्त हो नई फाइल।)

संपादित करें: उचित समापन टैग पर अलगाव करने के बारे में आपकी टिप्पणी के आधार पर, आपको शायद ऐसे टैग का पता लगाने के लिए एल्गोरिदम विकसित करना होगा (शायद peek विधि का उपयोग करके) नियमित अभिव्यक्ति का उपयोग करना।

2

यदि आप लिनक्स/यूनिक्स पर हैं, तो this guy जैसे स्प्लिट कमांड का उपयोग क्यों न करें?

split --bytes=100m /input/file /output/dir/prefix 

संपादित करें: फिर csplit का उपयोग करें।

+1

यह काम नहीं करेगा क्योंकि मेरे पास एक एक्सएमएल फ़ाइल है। मुझे प्रत्येक फ़ाइल को सही स्थान पर विभाजित करने की आवश्यकता होगी (समापन टैग के साथ पूर्ण रिकॉर्ड के बाद)। – Maulin

+0

@ मौलिन। आउच ... एक दिलचस्प समस्या के लिए बनाता है हालांकि –

0

अगर समय एक प्रमुख कारक (या पहनते हैं और अपने डिस्क ड्राइव पर आंसू) नहीं है: (कारण फाइल करने के लिए

  1. ओपन संभाल
  2. अपने विभाजन/तार्किक तोड़ने बिंदु के आकार तक पढ़ा गया xml)
  3. (डिस्क के लिए अपनी फ़ाइल के बाकी सहेजें यकीन नहीं कैसे अजगर यह जहाँ तक सीधे अधिलेखन फ़ाइल या स्मृति उपयोग)
  4. डिस्क
  5. गोटो 1
  6. करने के लिए विभाजन लिखें संभालती

अजगर आप नियंत्रण के इस स्तर नहीं देता है, तो आप आप हमेशा एक्सएमएल फ़ाइल को पार्स करने और बाहर लिख सकता है सी

0

में गोता लगाने की आवश्यकता हो सकती है कि वहाँ अपनी फ़ाइल के लिए हर 10000 तत्व कहते हैं। इस लिंक के बढ़ते पार्सिंग सेक्शन को देखें। http://effbot.org/zone/element-iterparse.htm

-1

यह एक नया हार्ड ड्राइव खरीदने का समय है!

आप सभी अन्य उत्तर प्रयास करने से पहले बैकअप बना सकते हैं और डेटा खो :)

0

यहाँ मेरी स्क्रिप्ट है नहीं मिलता है ...

import string 
import os 
from ftplib import FTP 

# make ftp connection 
ftp = FTP('server') 
ftp.login('user', 'pwd') 
ftp.cwd('/dir') 

f1 = open('large_file.xml', 'r') 

size = 0 
split = False 
count = 0 

for line in f1: 
    if not split: 
    file = 'split_'+str(count)+'.xml' 
    f2 = open(file, 'w') 
    if count > 0: 
     f2.write('<?xml version="1.0"?>\n') 
     f2.write('<StartTag xmlns="http://www.blah/1.2.0">\n') 
    size = 0 
    count += 1 
    split = True  
    if size < 1073741824: 
     f2.write(line) 
     size += len(line) 
    elif str(line) == '</EndTag>\n': 
     f2.write(line) 
     f2.write('</EndEndTag>\n') 
     print('completed file %s' %str(count)) 
     f2.close() 
     f2 = open(file, 'r') 
     print("ftp'ing file...") 
     ftp.storbinary('STOR ' + file, f2) 
     print('ftp done.') 
     split = False 
     f2.close() 
     os.remove(file) 
    else: 
    f2.write(line) 
    size += len(line) 
संबंधित मुद्दे