2013-07-15 5 views
6

से पढ़ने के बाद एक ही फ़ाइल में वापस लिखना मेरा लक्ष्य फ़ाइल से रेखा को पढ़ना है, इसके अंत में रिक्त स्थान को पट्टी करना और उसी फ़ाइल में वापस लिखना है। मैंने निम्नलिखित कोड का प्रयास किया है:फ़ाइल

with open(filename, 'r+') as f: 
    for i in f: 
     f.write(i.rstrip()+"\n") 

फ़ाइल के प्रारंभिक डेटा को बरकरार रखते हुए, फ़ाइल के अंत में यह लिखने लगता है। मुझे पता है कि f.seek(0) का उपयोग कर फ़ाइल को शुरू करने के लिए पॉइंटर वापस ले जाएगा, जो मुझे लगता है कि इस समाधान के लिए किसी भी तरह की आवश्यकता होगी।

क्या आप कृपया सलाह दे सकते हैं कि इसके लिए अलग दृष्टिकोण है या मैं सही पैच पर हूं, बस कोड में और तर्क जोड़ने की आवश्यकता है?

उत्तर

5

एक अस्थायी फ़ाइल का उपयोग करें। पाइथन एक सुरक्षित तरीके से अस्थायी फ़ाइलों को बनाने के लिए सुविधाएं प्रदान करता है। यहां अजगर modify.py target_filename

import tempfile 
import sys 

def modify_file(filename): 

     #Create temporary file read/write 
     t = tempfile.NamedTemporaryFile(mode="r+") 

     #Open input file read-only 
     i = open(filename, 'r') 

     #Copy input file to temporary file, modifying as we go 
     for line in i: 
      t.write(line.rstrip()+"\n") 

     i.close() #Close input file 

     t.seek(0) #Rewind temporary file to beginning 

     o = open(filename, "w") #Reopen input file writable 

     #Overwriting original file with temporary file contents   
     for line in t: 
      o.write(line) 

     t.close() #Close temporary file, will cause it to be deleted 

if __name__ == "__main__": 
     modify_file(sys.argv[1]) 

संदर्भ:: के साथ नीचे दिए गए उदाहरण कॉल http://docs.python.org/2/library/tempfile.html

+0

अच्छा उदाहरण और महान स्पष्टीकरण। – misguided

+0

धन्यवाद। मुझे स्मृति उपलब्ध होने पर भी अस्थायी फ़ाइलों का उपयोग करना पसंद है। Tempfile दस्तावेज़ों में स्पूल की गई अस्थायी फ़ाइल को भी देखें, जो एक दिलचस्प समझौता देता है। – JonnyRo

1

आपके दृष्टिकोण में समस्या यह है कि आपको एक इनपुट स्ट्रीम और आउटपुट स्ट्रीम दोनों की आवश्यकता है, जो एक ही फ़ाइल में विभिन्न स्थानों पर इंगित कर सकते हैं। यदि आप f.seek() का उपयोग करना चाहते हैं तो आपको प्रत्येक पढ़ने और लिखने के बाद f.tell() का उपयोग करके स्थिति को स्टोर करने की आवश्यकता होगी। उदाहरण के लिए:

f = open(filename, 'r+') 
while True: 
    i = f.readline() 
    if i == '': break 
    in = f.tell() 
    f.seek(out) 
    f.write(i.rstrip()+"\n") 
    out = f.tell() 
    f.seek(in) 

लेकिन यह भ्रमित और त्रुटियों के लिए प्रवण है। अगर फ़ाइल बहुत बड़ी नहीं है, तो इसे सब मेमोरी में क्यों न पढ़ें और फिर इसे फिर से लिखें?

in = open(filename, 'r') 
lines = in.read() 
in.close() 
out = open(filename, 'w') 
out.write([line.rstrip()+'\n' for line in lines.split('\n')]) 
out.close() 

फ़ाइल स्मृति में फिट करने के लिए है, तो एक अस्थायी फ़ाइल को पंक्तियां लिखें और फिर फ़ाइल का नाम बदलने जब आप पूरा कर बहुत बड़ी है, तो:

out = open(filename+'.tmp', 'w') 
with open(filename, 'r') as f: 
    for i in f: 
     out.write(i.rstrip()+"\n") 
out.close() 
os.rename(filename+'.tmp', filename) 
+0

अपने अंतिम समाधान लगभग मुद्दे को हल करने के लिए लगता है, केवल मुद्दा शेष जा रहा है, मैं नया फ़ाइल नाम बदलने के लिए करना चाहते हैं यानी, नई फाइल पुरानी फाइल को प्रतिस्थापित करनी चाहिए। यदि मैं उपरोक्त निर्दिष्ट विधि से करता हूं, तो मुझे 'विंडोज त्रुटि: [त्रुटि 183] फ़ाइल नहीं बना सकती है जब वह फ़ाइल पहले से मौजूद है' – misguided

+1

यह आसान है, इसे बंद करने के बाद पुरानी फ़ाइल को हटा दें लेकिन इसे नाम देने से पहले: os.remove (फ़ाइल नाम) ' –