डी

2011-01-17 13 views
8

में टेक्स्ट फ़ाइल पढ़ें क्या डी में टेक्स्ट फ़ाइल पढ़ने के लिए कोई भी आकार-फिट-सब (अधिक या कम) तरीका है?डी

आवश्यकता यह है कि फ़ंक्शन एन्कोडिंग को स्वतः पहचान लेगा और मुझे फ़ाइल के पूरे डेटा को एक सतत प्रारूप में string या dstring प्रदान करेगा। इसे बीओएम को स्वतः पहचानना चाहिए और उन्हें उचित रूप से समझना चाहिए।

मैंने std.file.readText() की कोशिश की लेकिन यह अलग-अलग एन्कोडिंग को अच्छी तरह से संभाल नहीं पाता है।

(बेशक, यह एक गैर शून्य असफलता की दर होगा, और है कि अपने आवेदन के लिए स्वीकार्य है।)

उत्तर

8

मुझे विश्वास है कि मैं इस बिंदु पर फोबोस में/ओ (से अलग फ़ाइल के लिए केवल वास्तविक विकल्प कॉलिंग फंक्शन) std.file.readText और std.stdio.File हैं। readText एक फ़ाइल में वर्ण, wchars, या dchars (अपरिवर्तनीय (char) [] - i.e. स्ट्रिंग के लिए डिफ़ॉल्ट) के रूप में एक फ़ाइल में पढ़ा जाएगा। मेरा मानना ​​है कि एन्कोडिंग क्रमशः वर्ण, wchars, और dchars के लिए यूटीएफ -8, यूटीएफ -16, और यूटीएफ -32 होना चाहिए, हालांकि मुझे सुनिश्चित करने के लिए स्रोत कोड में खुदाई करना होगा। कोई भी एन्कोडिंग जो उन एन्कोडिंग के साथ संगत है (उदा। ASCII यूटीएफ -8 के साथ संगत है) को ठीक काम करना चाहिए।

यदि आप File का उपयोग करते हैं, तो आपके पास readln और rawRead सहित फ़ाइल को पढ़ने के लिए फ़ंक्शंस के लिए कई विकल्प हैं। हालांकि, आप अनिवार्य रूप से readText के साथ यूटीएफ -8, यूटीएफ -16, या यूटीएफ -32 संगत एन्कोडिंग का उपयोग करने में फ़ाइल को पढ़ते हैं, या आप इसे बाइनरी डेटा के रूप में पढ़ते हैं और इसे स्वयं कुशल बनाते हैं।

चूंकि डी में वर्ण प्रकार चार, Wchar, और dchar हैं, जो यूटीएफ -8, यूटीएफ -16, और यूटीएफ -32 कोड इकाइयां हैं, जब तक कि आप बाइनरी प्रारूप में डेटा को पढ़ना नहीं चाहते हैं, फ़ाइल उन तीन प्रकार के यूनिकोड में से एक के साथ संगत एन्कोडिंग में एन्कोड किया जाना है। किसी विशेष एन्कोडिंग में एक स्ट्रिंग को देखते हुए, आप std.utf में फ़ंक्शंस का उपयोग करके इसे दूसरे एन्कोडिंग में परिवर्तित कर सकते हैं। हालांकि, मुझे दिए गए एन्कोडिंग में फ़ाइल को आजमाने और पढ़ने के लिए readText का उपयोग करने के अलावा अपने एन्कोडिंग प्रकार के लिए फ़ाइल से पूछने के किसी भी तरीके से अवगत नहीं है और देखें कि यह सफल होता है या नहीं।

तो, जब तक कि आप स्वयं फ़ाइल को संसाधित नहीं करना चाहते हैं और फ्लाई पर निर्धारित करना चाहते हैं कि इसमें क्या एन्कोडिंग है, तो आपकी सबसे अच्छी शर्त संभवतया प्रत्येक स्ट्रिंग प्रकार के साथ readText का उपयोग करने के लिए संभव है, जो पहले सफल होता है। हालांकि, चूंकि टेक्स्ट फाइलें आमतौर पर यूटीएफ -8 या यूटीएफ -8 संगत एन्कोडिंग में होती हैं, इसलिए मैं उम्मीद करता हूं कि readText सामान्य स्ट्रिंग के साथ उपयोग किया जाता है, जो लगभग हमेशा ठीक काम करता है।

+0

एचएम ... कोई विचार है कि बीओएम के साथ क्या करना है? – Mehrdad

+1

@ लैम्बर्ट, मैं अत्यधिक पढ़ने() का उपयोग करने का सुझाव देता हूं क्योंकि यह कोई सत्यापन नहीं करेगा, लेकिन आप इसे स्वयं कर सकते हैं और फ़ाइल को कई बार नहीं पढ़ रहे हैं। बीओएम के लिए आप यूबेट में डाल सकते हैं और पहले बाइट्स की तुलना कर सकते हैं, फिर बाकी स्लाइस के लिए एक कास्ट करें ... –

+0

एचएम ... जिस समाधान की मैं उम्मीद कर रहा था वह नहीं (मैं मैन्युअल रूप से बीओएम की जांच नहीं करना चाहता था) लेकिन मुझे लगता है कि यह बहुत बुरा नहीं है; धन्यवाद। – Mehrdad

4

बीओएम जाँच से निपटने के लिए के रूप में:

char[] ConvertViaBOM(ubyte[] data) { 
    char[] UTF8() { /*...*/ } 
    char[] UTF16LE(){ /*...*/ } 
    char[] UTF16BE(){ /*...*/ } 
    char[] UTF32LE(){ /*...*/ } 
    char[] UTF32BE(){ /*...*/ } 

    switch (data.length) { 
    default: 
    case 4: 
     if (data[0..4] == [cast(ubyte)0x00, 0x00, 0xFE, 0xFF]) return UTF32BE(); 
     if (data[0..4] == [cast(ubyte)0xFF, 0xFE, 0x00, 0x00]) return UTF32LE(); 
     goto case 3; 

    case 3: 
     if (data[0..3] == [cast(ubyte)0xEF, 0xBB, 0xBF]) return UTF8(); 
     goto case 2; 

    case 2: 
     if (data[0..2] == [cast(ubyte)0xFE, 0xFF]) return UTF16BE(); 
     if (data[0..2] == [cast(ubyte)0xFF, 0xFE]) return UTF16LE(); 
     goto case 1; 

    case 1: 
     return UTF8(); 
    } 
} 

जोड़ना अधिक अस्पष्ट बीओएम के पाठक के लिए एक व्यायाम के रूप में छोड़ दिया जाता है।