2012-03-10 14 views
38

'आर' मोड में एक टेक्स्ट फ़ाइल को पार्सिंग करने से 'आरबी' मोड में इसे पार्स करने से अधिक सुविधाजनक क्या होता है? खासकर जब प्रश्न में टेक्स्ट फ़ाइल में गैर-ASCII वर्ण हो सकते हैं।आर और आरबी मोड में एक पाठ फ़ाइल को पार्स करने के बीच अंतर

+0

क्या आप एक टेक्स्ट फ़ाइल या बाइनरी फ़ाइल पढ़ रहे हैं? –

+0

एक टेक्स्ट फ़ाइल। लेकिन किसी भी कारण से मुझे फ़ाइल को बाइट-स्ट्रीम के रूप में दिया गया है। – MxyL

उत्तर

44

यह आपके द्वारा उपयोग किए जाने वाले पायथन के संस्करण पर थोड़ा सा निर्भर करता है। पायथन 2 में, Chris Drappier's answer लागू होता है।

पायथन 3 में, यह एक अलग (और अधिक संगत) कहानी है: पाठ मोड ('r') में, पाइथन आपके द्वारा दिए गए टेक्स्ट एन्कोडिंग के अनुसार फ़ाइल को पार्स करेगा (या, यदि आप एक नहीं देते हैं, तो मंच-निर्भर डिफ़ॉल्ट), और read() आपको str देगा। बाइनरी ('rb') मोड में, पायथन यह नहीं मानता कि फ़ाइल में ऐसी चीजें हैं जिन्हें उचित रूप से वर्णों के रूप में पार्स किया जा सकता है, और read() आपको bytes ऑब्जेक्ट देता है।

इसके अलावा, अजगर 3, सार्वभौमिक नई-पंक्तियों ('\n' और प्लेटफ़ॉर्म-विशिष्ट न्यू लाइन सम्मेलनों के बीच अनुवाद ताकि आप उन्हें के बारे में परवाह करने की जरूरत नहीं) में पर किसी भी मंच पाठ मोड फ़ाइलों के लिए उपलब्ध है, न सिर्फ विंडोज।

+0

, पाठ मोड में पढ़ना स्वचालित रूप से यह पता लगाने का प्रयास करेगा कि यह किस प्रकार का एन्कोडिंग है? मुझे लगता है कि एन्कोडिंग का पता लगाना एक बाइट ऑब्जेक्ट के साथ काफी चुनौती है। – MxyL

+1

@Keikoku बिना किसी मेटाडाटा के, अकेले स्ट्रीम पर आधारित एन्कोडिंग का पता लगाना असंभव है - विभिन्न एन्कोडिंग के बारे में सोचें जो ASCII + समानता के बजाय जानकारी के लिए 8 वें बिट का उपयोग करते हैं; वे सभी 255 मान्य वन-बाइट अनुक्रम साझा करते हैं, लेकिन उनमें से केवल आधा (ASCII आधा) प्रत्येक में एक ही चरित्र का प्रतिनिधित्व करता है। पायथन का डिफ़ॉल्ट अनुमान लगाने का अनुमान नहीं है, यह एक सत्र-व्यापी डिफ़ॉल्ट एन्कोडिंग है, जिसे 'sys.getdefaultencoding() 'लिखा गया है। मेरे Py3 इंस्टॉल पर, इसकी यूटीएफ -8, लेकिन आप उस मामले पर हमेशा भरोसा नहीं कर सकते हैं। – lvc

19
documentation से

:

Windows पर, 'बी' मोड के साथ जोड़ दिया द्विआधारी मोड में फ़ाइल को खोलता है, इसलिए वहाँ भी 'rb', 'पश्चिम बंगाल', और 'आर + बी की तरह मोड हैं '। विंडोज़ पर पायथन टेक्स्ट और बाइनरी फाइलों के बीच एक अंतर बनाता है; जब डेटा पढ़ा या लिखा जाता है तो पाठ फ़ाइलों में अंत-पंक्ति वर्ण स्वचालित रूप से थोड़ा बदल जाते हैं। फ़ाइल डेटा में यह दृश्य-दृश्य दृश्य ASCII टेक्स्ट फ़ाइलों के लिए ठीक है, लेकिन यह जेपीईजी या EXE फ़ाइलों में बाइनरी डेटा दूषित कर देगा। ऐसी फाइलें पढ़ने और लिखते समय बाइनरी मोड का उपयोग करने के लिए बहुत सावधान रहें। यूनिक्स पर, यह मोड में 'बी' जोड़ने में कोई दिक्कत नहीं होती है, इसलिए आप इसे सभी बाइनरी फ़ाइलों के लिए स्वतंत्र रूप से मंच का उपयोग कर सकते हैं।

+0

तो मूल रूप से बाइनरी मोड में लाइनों को पढ़ने की कोशिश करना अधिक कठिन है क्योंकि मुझे गारंटी नहीं है कि ईओएल चरित्र \ n या \ r \ n या कुछ और है? Py3 के लिए – MxyL

8

अंतर यह है कि अंत-रेखा (ईओएल) को कैसे संभाला जाता है। विंडोज़ में ओएस एक्स, \r\n से पहले मैक संस्करणों में यूनिक्स, \r में ईओएल - \n को चिह्नित करने के लिए विभिन्न ऑपरेटिंग सिस्टम अलग-अलग वर्णों का उपयोग करते हैं। जब टेक्स्ट मोड में फ़ाइल खोला जाता है, जब फ़ाइल पढ़ी जाती है, तो पायथन फ़ाइल से पढ़ने वाले ओएस विशिष्ट एंड-ऑफ-लाइन वर्ण को \n के साथ बदल देता है। और इसके विपरीत, यानी जब आप पाठ मोड में खोले गए फ़ाइल में \n लिखने का प्रयास करते हैं, तो यह ओएस विशिष्ट ईओएल चरित्र लिखने जा रहा है। os.linesep की जांच करके आप अपने ओएस डिफ़ॉल्ट ईओएल को पा सकते हैं।

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

पायथन में एक सार्वभौमिक न्यूलाइन मोड भी है। जब इस मोड में एक फ़ाइल खोली जाती है, तो पाइथन \r, \n और \r\n से \n पर सभी वर्णों को मानचित्रित करता है।

+0

क्या यह पाइथन 2 और पायथन 3 दोनों के लिए सच है? – Agostino

2

स्पष्टीकरण के लिए और Agostino's comment/question जवाब देने के लिए (मैं इतना टिप्पणी मुझे एक जवाब के रूप में इस बताते हुए के साथ सहन करने के लिए पर्याप्त प्रतिष्ठा नहीं है ...):

अजगर 2 में कोई लाइन अंत संशोधन होता है, न तो पाठ में न ही बाइनरी मोड - जैसा कि पहले बताया गया है, पाइथन 2 Chris Drappier's answer में लागू होता है (कृपया ध्यान दें कि इसका लिंक आजकल 3 को इंगित करता है।एक्स अजगर डॉक्स लेकिन 'क्रिस उद्धृत पाठ Python 2 input and output tutorial से निश्चित रूप से है)

तो नहीं, यह सच नहीं है कि गैर- Windows पर पायथन 2 साथ पाठ मोड में एक फ़ाइल को खोलने के लिए किसी भी लाइन अंत करता है संशोधन:

0 $ python2.7 -c 'f = open("data.txt", "rU"); print f.readlines()' 
['line1\n', 'line2\n', 'line3\n'] 
:

0 $ cat data.txt 
line1 
line2 
line3 
0 $ file data.txt 
data.txt: ASCII text, with CRLF line terminators 
0 $ python2.7 -c 'f = open("data.txt"); print f.readlines()' 
['line1\r\n', 'line2\r\n', 'line3\r\n'] 
0 $ python2.7 -c 'f = open("data.txt", "r"); print f.readlines()' 
['line1\r\n', 'line2\r\n', 'line3\r\n'] 
0 $ python2.7 -c 'f = open("data.txt", "rb"); print f.readlines()' 

यह अजगर 2, करता है जो वास्तव में प्रदर्शन कहा लाइन अंत आधुनिक में सार्वभौमिक न्यू लाइन मोड में फ़ाइल खोलने के लिए हालांकि संभव है

अजगर 3 पर, दूसरे हाथ पर, प्लेटफ़ॉर्म-विशिष्ट लाइन के लिए '\ n' जब पाठ में एक फ़ाइल को पढ़ने सामान्यीकृत मिलता है समाप्त होता है (सार्वभौमिक न्यू लाइन मोड विनिर्देशक अजगर 3.x के रूप में हटा दिया गया है) मोड, और '\ n' पाठ मोड में लिखते समय वर्तमान प्लेटफॉर्म के डिफ़ॉल्ट पंक्ति अंत में परिवर्तित हो जाता है (बाइट्स < -> यूनिकोड < -> बाइट्स डिकोडिंग/एन्कोडिंग टेक्स्ट मोड में चल रहा है) के अलावा। जैसे लिनक्स पर एक डॉस/विन सीआरएलएफ-लाइन-एंडेड फाइल पढ़ने से लाइन को '\ n' तक समाप्त कर दिया जाएगा।

+0

python3 की खुली समारोह को नियंत्रित करने कि जरूरत पड़ने पर https://docs.python.org/3/library/functions.html#open "न्यू लाइन नियंत्रण कैसे सार्वभौमिक नई-पंक्तियों मोड में काम करता है (यह केवल पाठ पर लागू होता है एक नई पंक्ति पैरामीटर है मोड)। यह कोई नहीं हो सकता है, '', '\ n', '\ r', और '\ r \ n'। यह निम्नानुसार काम करता है: स्ट्रीम से इनपुट पढ़ने पर, यदि नई लाइन कोई नहीं है, तो सार्वभौमिक न्यूलाइन मोड है सक्षम " – Davos

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

  • कोई संबंधित समस्या नहीं^_^