2010-10-11 14 views
56

एक अभ्यास के लिए मैं कर रहा हूं, मैं read() विधि का उपयोग करके दो बार दी गई फ़ाइल की सामग्री को पढ़ने की कोशिश कर रहा हूं। आश्चर्यजनक रूप से, जब मैं इसे दूसरी बार कॉल करता हूं, तो यह फ़ाइल सामग्री को एक स्ट्रिंग के रूप में वापस नहीं प्रतीत होता है?मैं खुली फ़ाइल पर दो बार क्यों पढ़ नहीं सकता?

यहाँ कोड

f = f.open() 

# get the year 
match = re.search(r'Popularity in (\d+)', f.read()) 

if match: 
    print match.group(1) 

# get all the names 
matches = re.findall(r'<td>(\d+)</td><td>(\w+)</td><td>(\w+)</td>', f.read()) 

if matches: 
    # matches is always None 

बेशक मुझे पता है कि यह सबसे कारगर या सबसे अच्छा तरीका नहीं है, इस बात यहाँ नहीं है। मुद्दा यह है कि, मैं read() को दो बार क्यों नहीं बुला सकता? क्या मुझे फ़ाइल हैंडल रीसेट करना है? या ऐसा करने के लिए फ़ाइल को बंद/दोबारा खोलें?

+2

आपको यह विचार कहां मिला कि फ़ाइल की स्थिति में बदलाव नहीं आएगा? आप किस संदर्भ या ट्यूटोरियल का उपयोग कर रहे हैं? –

+0

मेरा मानना ​​है कि फाइल को बंद करना और फिर से खोलना चाहिए नीचे दिए गए एवरों के आधार पर काम करना चाहिए। – Anthony

+0

@Shynthriir: फ़ाइल को बंद करना और फिर से खोलना हमेशा एक अच्छा विचार नहीं है क्योंकि इसका सिस्टम (अस्थायी फ़ाइलें, incron, आदि) में अन्य प्रभाव हो सकते हैं। –

उत्तर

88

कॉलिंग read() पूरी फ़ाइल के माध्यम से पढ़ता है और फ़ाइल के अंत में पढ़ने वाले कर्सर को छोड़ देता है (पढ़ने के लिए और कुछ भी नहीं)। यदि आप एक समय में लाइनों की एक निश्चित संख्या को पढ़ना चाहते हैं तो आप readline(), readlines() का उपयोग कर सकते हैं या for line in handle: के साथ लाइनों के माध्यम से पुनरावृत्त कर सकते हैं।

आपके सवाल का सीधे जवाब देने के लिए, एक बार एक फ़ाइल को पढ़ने की गई है, read() साथ आप seek(0) उपयोग कर सकते हैं फ़ाइल के शुरू करने के पढ़ने कर्सर वापस जाने के लिए (डॉक्स here हैं)। यदि आप जानते हैं कि फ़ाइल बहुत बड़ी नहीं होगी, तो आप अपने निष्कर्ष अभिव्यक्तियों में इसका उपयोग करके read() आउटपुट को एक चर में भी सहेज सकते हैं।

Ps। फ़ाइल के साथ किए जाने के बाद फ़ाइल को बंद करना न भूलें;)

+3

+1, हां, कृपया अस्थायी चर में पढ़ें अनावश्यक फ़ाइल I/O से बचें। यह एक झूठी अर्थव्यवस्था है कि आप किसी भी स्मृति को सहेज रहे हैं क्योंकि आपके पास कम (स्पष्ट) चर हैं। –

+2

@NickT: मुझे उम्मीद है कि एक छोटी फ़ाइल को कई बार पढ़ा जा रहा है ओएस (कम से कम लिनक्स/ओएसएक्स पर) कैश किया जाता है, इसलिए दो बार पढ़ने के लिए कोई अतिरिक्त फ़ाइल I/O नहीं है। बड़ी फाइलें जो स्मृति में फिट नहीं होती हैं उन्हें कैश नहीं मिलता है, लेकिन आप उन्हें एक चर में नहीं पढ़ना चाहते हैं क्योंकि आप स्वैपिंग शुरू कर देंगे। तो संदेह के मामले में, हमेशा कई बार पढ़ें। यदि आप निश्चित रूप से जानते हैं कि फाइलें छोटी हैं, तो जो भी सबसे अच्छा प्रोग्राम देता है। – Claude

+0

आंसू नीचे ['with'] (http://effbot.org/zone/python-with-statement.htm) के साथ स्वचालित किया जा सकता है। –

13

पढ़ा गया सूचक अंतिम बार बाइट/चरित्र के बाद चलता है। शुरुआत में पढ़ने वाले सूचक को रिवाइंड करने के लिए seek() विधि का उपयोग करें।

2

प्रत्येक खुली फ़ाइल में एक संबद्ध स्थिति है।
जब आप पढ़ते हैं() आप उस स्थिति से पढ़ते हैं। उदाहरण के लिए read(10) नई खुली फ़ाइल से पहले 10 बाइट्स पढ़ता है, तो अगला read(10) अगले 10 बाइट्स पढ़ता है। read() तर्क के बिना फ़ाइल की सभी सामग्री को पढ़ता है, फ़ाइल के अंत में फ़ाइल स्थिति छोड़ देता है। अगली बार जब आप read() पर कॉल करेंगे तो पढ़ने के लिए कुछ भी नहीं है।

आप फ़ाइल स्थिति को स्थानांतरित करने के लिए seek का उपयोग कर सकते हैं। या शायद आपके मामले में बेहतर एक read() करना होगा और दोनों खोजों के लिए परिणाम रखें।

13

हर कोई जिसने अभी तक इस प्रश्न का उत्तर दिया है वह बिल्कुल सही है - read() फ़ाइल के माध्यम से चलता है, इसलिए इसे कहने के बाद, आप इसे फिर से कॉल नहीं कर सकते हैं।

मैं जो जोड़ूं, वह यह है कि आपके विशेष मामले में, आपको फ़ाइल को शुरू या फिर से खोलने की आवश्यकता नहीं है, आप केवल उस पाठ को संग्रहीत कर सकते हैं जिसे आपने स्थानीय चर में पढ़ा है, और उपयोग इसे दो बार, या के रूप में कई बार के रूप में आप की तरह, अपने कार्यक्रम में:

f = f.open() 
text = f.read() # read the file into a local variable 
# get the year 
match = re.search(r'Popularity in (\d+)', text) 
if match: 
    print match.group(1) 
# get all the names 
matches = re.findall(r'<td>(\d+)</td><td>(\w+)</td><td>(\w+)</td>', text) 
if matches: 
    # matches will now not always be None 
+1

+1 वास्तव में यह इस अभ्यास के लिए प्रस्तावित समाधान था (http://code.google.com/intl/de-DE/edu/languages/google-python-class/exercises/baby-names.html)। लेकिन किसी भी तरह से मैंने एक चर में स्ट्रिंग को संग्रहीत करने का विचार नहीं किया था। डी 'ओह! – helpermethod

+1

पायथन 3 के साथ, pathlib का उपयोग करें। 'pathlib आयात पथ से; पाठ = पथ (फ़ाइल नाम) .read_text() 'खुले, करीबी, आदि की देखभाल करता है। – PaulMcG

1

read() खपत करता है। तो, आप रीसेट पढ़ने से पहले रीसेट कर सकते हैं, या को री-रीडिंग से पहले शुरू कर सकते हैं। या, यदि यह आपके कार्य को सुइट करता है, तो आप read(n) का उपयोग केवल n बाइट्स उपभोग करने के लिए कर सकते हैं।

12

हाँ, ऊपर के रूप में ...

>>> a = open('file.txt') 
>>> a.read() 
#output 
>>> a.seek(0) 
>>> a.read() 
#same output 
1

मैं हमेशा एक अंधेरे गली नीचे टहलने के पढ़ने विधि कुछ पाते हैं:

मैं सिर्फ एक उदाहरण लिखेंगे। आप थोड़ा नीचे जाते हैं और रुकते हैं लेकिन यदि आप अपने कदमों की गिनती नहीं कर रहे हैं तो आप निश्चित नहीं हैं कि आप कितने दूर हैं। खोज पुनर्स्थापना द्वारा समाधान देता है, दूसरा विकल्प बताता है जो फ़ाइल के साथ स्थिति देता है। पाइथन फ़ाइल एपीआई पढ़ सकते हैं और इसे आसान बनाने के लिए read_from (स्थिति, बाइट्स) में खोज सकते हैं - ऐसा होने तक आपको this page पढ़ना चाहिए।

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