2009-02-12 11 views
29

मैं डेटा फीड का उपभोग कर रहा हूं जिसने हाल ही में यूनिकोड बीओएम हेडर (यू + एफईएफएफ) जोड़ा है, और मेरा रेक कार्य अब इसके द्वारा गड़बड़ कर रहा है।फ़ाइलों को पढ़ने पर यूटीएफ -8 बीओएम पर ट्रिपिंग से बचने के लिए कैसे करें

मैं file.gets[3..-1] के साथ पहले 3 बाइट्स को छोड़ सकता हूं लेकिन रूबी में फ़ाइलों को पढ़ने के लिए एक और शानदार तरीका है जो यह सही ढंग से संभाल सकता है, भले ही बीओएम मौजूद है या नहीं?

+2

एक यूनिकोड बीओएम एक यूटीएफ -8 एक नहीं है। – AnthonyWJones

+0

धन्यवाद, मुझे बस एहसास हुआ। यह वास्तव में 3 बाइट्स है, एक नहीं ... मैंने सवाल को इतना कहने के लिए संपादित किया। –

उत्तर

48

माणिक के साथ 1.9.2 आप मोड का उपयोग कर सकते हैं r:bom|utf-8

text_without_bom = nil #define the variable outside the block to keep the data 
File.open('file.txt', "r:bom|utf-8"){|file| 
    text_without_bom = file.read 
} 

या

text_without_bom = File.read('file.txt', encoding: 'bom|utf-8') 

या

text_without_bom = File.read('file.txt', mode: 'r:bom|utf-8') 

यह कोई फर्क नहीं पड़ता, अगर बीओएम में उपलब्ध है फ़ाइल या नहीं।


तुम भी अन्य आदेशों के साथ एन्कोडिंग विकल्प का उपयोग कर सकते हैं:

text_without_bom = File.readlines(@filename, "r:utf-8") 

(आप सभी लाइनों के साथ एक सरणी मिल)।

या सीएसवी साथ:

require 'csv' 
CSV.open(@filename, 'r:bom|utf-8'){|csv| 
    csv.each{ |row| p row } 
} 
+0

क्या रूबी में निर्मित सीएसवी लाइब्रेरी का उपयोग कर सीएसवी फाइलों के साथ ऐसा करने का कोई तरीका है? मैंने सीएसवी के फोरच को ': एन्कोडिंग => "आर: बॉम | यूटीएफ -8"' पास करने का प्रयास किया है, लेकिन यह अभी भी बीओएम पढ़ता है जैसे कि यह हेडर के पहले कॉलम का हिस्सा है। – Aaron

+2

मुझे लगता है कि यह संभव है। 'सीवीएस.read (फ़ाइल नाम,: एन्कोडिंग => 'utf-8') के साथ 'आप सीएसवी के साथ एन्कोडिंग सेट कर सकते हैं (या यह' CSV.load' है?)। मुझे लगता है कि यह शोर भी बॉम-तर्क के साथ संभव है: ': एन्कोडिंग => 'बॉम | utf-8')'। मैं वास्तव में खुद का परीक्षण नहीं कर सकता - क्षमा करें। – knut

+0

निम्नलिखित मेरे लिए काम किया: 'file = file.open (@filename, 'r: bom | utf-8')' 'csv = CSV.new (फ़ाइल, fast_csv_options)' 'csv.each do | पंक्ति | '... ' file.close' – Aaron

10

मैं पहले तीन बाइट्स को अंधाधुंध नहीं छोड़ूंगा; क्या होगा अगर निर्माता फिर से बीओएम जोड़ता है? आपको क्या करना चाहिए पहले कुछ बाइट्स जांचें, और यदि वे 0xEF 0xBB 0xBF हैं, तो उन्हें अनदेखा करें। यही वह रूप है जो बीओएम चरित्र (यू + एफईएफएफ) यूटीएफ -8 में होता है; स्ट्रीम को डीकोड करने की कोशिश करने से पहले मैं इससे निपटना पसंद करता हूं क्योंकि बीओएम हैंडलिंग एक भाषा/उपकरण/ढांचे से अगले तक असंगत है।

वास्तव में, यह है कि आप किसी बीओएम से निपटने के लिए हैं। यदि यूटीएफ -16 के रूप में एक फाइल परोसा गया है, तो आपको डीकोडिंग शुरू करने से पहले पहले दो बाइट्स की जांच करनी होगी ताकि आपको पता चले कि इसे बड़े-एंडियन या छोटे-एंडियन के रूप में पढ़ना है या नहीं। बेशक, यूटीएफ -8 बीओएम के पास बाइट ऑर्डर के साथ कुछ लेना देना नहीं है, यह आपको यह बताने के लिए है कि एन्कोडिंग यूटीएफ -8 है, अगर आपको पहले से ही यह पता नहीं था।

0

मैं "विश्वास" कुछ फ़ाइल नहीं UTF-8 जब 0xEF 0xBB 0xBF की एक बीओएम मौजूद है, तो आप असफल हो सकता है के रूप में एन्कोड करने की होगी। आमतौर पर यूटीएफ -8 बीओएम का पता लगाने पर, यह वास्तव में एक यूटीएफ -8 एन्कोडेड फ़ाइल होना चाहिए। लेकिन, अगर किसी उदाहरण के लिए किसी ने आईएसओ -8 बीओएम को एक आईएसओ फ़ाइल में जोड़ा है, तो आप 0x0F से ऊपर वाले बाइट्स में ऐसी फ़ाइल को इतना खराब करने में असफल हो जाएंगे। यदि आप केवल 0x0F तक बाइट्स हैं, तो आप फ़ाइल पर भरोसा कर सकते हैं, क्योंकि इस मामले में यह एक यूटीएफ -8 संगत ASCII फ़ाइल है और साथ ही यह एक वैध यूटीएफ -8 फ़ाइल है।

अगर वहाँ नहीं कर रहे हैं सिर्फ फ़ाइल के भीतर < = 0x0F बाइट्स (बीओएम के बाद), यह ठीक से UTF-8 एन्कोडेड आप मान्य दृश्यों और जांच करने के लिए होगा है सुनिश्चित करने के लिए - तब भी जब सभी दृश्यों मान्य हैं - यह भी जांचें कि अनुक्रम से प्रत्येक कोडपॉइंट कम से कम अनुक्रम का उपयोग करता है और यह भी जांचता है कि कोई कोडपॉइंट नहीं है जो उच्च या निम्न-सरोगेट से मेल खाता है। यह भी जांचें कि अनुक्रम का अधिकतम बाइट 4 से अधिक नहीं है और उच्चतम कोडपॉइंट 0x10FFFF है या नहीं। उच्चतम कोडपॉइंट सीमाएं स्टार्टबाइट की पेलोड बिट्स को 0x4 से अधिक नहीं होने वाली हैं और पहले निम्नलिखित बाइट के पेलोड 0xF से अधिक नहीं हैं। यदि सभी उल्लिखित चेक सफलतापूर्वक पास हो जाते हैं, तो आपका यूटीएफ -8 बीओएम सच बताता है।

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