2009-05-18 20 views
6

का उपयोग कर एक फ़ाइल स्ट्रीम डीकोड करें मेरे पास एक एक्सएमएल दस्तावेज़ है, जो बहुत बड़ा है (लगभग 120 एम), और मैं इसे एक बार में स्मृति में लोड नहीं करना चाहता हूं। मेरा उद्देश्य यह जांचना है कि यह फ़ाइल वैध यूटीएफ -8 एन्कोडिंग का उपयोग कर रही है या नहीं।यूटीएफ -8

byte[] के रूप में पूरी फ़ाइल को स्मृति में पढ़ने के बिना कोई त्वरित जांच करने के लिए कोई विचार है?

मैं वीएसटीएस 2008 और सी # का उपयोग कर रहा हूं।

वहाँ

जब XMLDocument का उपयोग कर एक XML दस्तावेज है, जो अवैध बाइट दृश्यों में शामिल है लोड करने के लिए, एक अपवाद है, लेकिन जब एक बाइट सरणी में सभी सामग्री को पढ़ने और फिर UTF-8 के खिलाफ जाँच, वहाँ कोई अपवाद नहीं है, किसी भी विचार?

यहाँ मेरी एक्सएमएल फ़ाइल की सामग्री को दिखाने वाले स्क्रीनशॉट है, या आप here

enter image description here

संपादित करें 1 से फ़ाइल की एक प्रतिलिपि डाउनलोड कर सकते हैं:

class Program 
{ 
    public static byte[] RawReadingTest(string fileName) 
    { 
     byte[] buff = null; 

     try 
     { 
      FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read); 
      BinaryReader br = new BinaryReader(fs); 
      long numBytes = new FileInfo(fileName).Length; 
      buff = br.ReadBytes((int)numBytes); 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine(ex.Message); 
     } 

     return buff; 
    } 

    static void XMLTest() 
    { 
     try 
     { 
      XmlDocument xDoc = new XmlDocument(); 
      xDoc.Load("c:\\abc.xml"); 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine(ex.Message); 
     } 
    } 

    static void Main() 
    { 
     try 
     { 
      XMLTest(); 
      Encoding ae = Encoding.GetEncoding("utf-8"); 
      string filename = "c:\\abc.xml"; 
      ae.GetString(RawReadingTest(filename)); 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine(ex.Message); 
     } 

     return; 
    } 
} 

संपादित करें 2:new UTF8Encoding(true, true) का उपयोग करते समय एक अपवाद होगा, लेकिन new UTF8Encoding(false, true) का उपयोग करते समय, कोई पूर्व नहीं है ception फेंक दिया। मैं उलझन में हूं, क्योंकि यह दूसरा पैरामीटर होना चाहिए जो नियंत्रित करता है कि कोई अपवाद फेंक दिया गया है (यदि अमान्य बाइट अनुक्रम हैं), पहला पैरामीटर क्यों मायने रखता है?

public static void TestTextReader2() 
    { 
     try 
     { 
      // Create an instance of StreamReader to read from a file. 
      // The using statement also closes the StreamReader. 
      using (StreamReader sr = new StreamReader(
       "c:\\a.xml", 
       new UTF8Encoding(true, true) 
       )) 
      { 
       int bufferSize = 10 * 1024 * 1024; //could be anything 
       char[] buffer = new char[bufferSize]; 
       // Read from the file until the end of the file is reached. 
       int actualsize = sr.Read(buffer, 0, bufferSize); 
       while (actualsize > 0) 
       { 
        actualsize = sr.Read(buffer, 0, bufferSize); 
       } 
      } 
     } 
     catch (Exception e) 
     { 
      // Let the user know what went wrong. 
      Console.WriteLine("The file could not be read:"); 
      Console.WriteLine(e.Message); 
     } 

    } 
+0

बाइट्स का लगभग कोई अनुक्रम नहीं है, यहां तक ​​कि यादृच्छिक बाइट मान, मान्य यूटीएफ 8? या क्या कुछ बाइट वैल्यू अनुक्रम हैं जो वैध यूटीएफ 8 नहीं हैं? – ChrisW

+1

उनमें से सभी, कुछ अपवाद हैं, कृपया यहां देखें, http://en.wikipedia.org/wiki/UTF-8#Invalid_code_points – George2

+1

@ChrisW: बिलकुल नहीं; यूटीएफ -8 में विशिष्ट एन्कोडिंग नियम हैं। –

उत्तर

5
var buffer = new char[32768] ; 

using (var stream = new StreamReader (pathToFile, 
    new UTF8Encoding (true, true))) 
{ 
    while (true) 
    try 
    { 
     if (stream.Read (buffer, 0, buffer.Length) == 0) 
      return GoodUTF8File ; 
    } 
    catch (ArgumentException) 
    { 
     return BadUTF8File ; 
    } 
} 
+0

लेकिन यदि एक वर्ण एकाधिक बाइट्स का उपयोग कर रहा है, तो आप इस तरह की स्थिति को कैसे संभालेंगे? – George2

+1

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

+0

@ सॉफ़्टवेयर बंदर, मैं उलझन में हूं कि आपका क्या मतलब है "पाठक वितरित करेगा" - क्या आप अपना कोड स्निपेट दिखा सकते हैं? – George2

3

@ George2 मुझे लगता है कि वे निम्नलिखित (जो मैं परीक्षण नहीं किया) की तरह एक समाधान मतलब है।

बफर के बीच संक्रमण को संभालना (यानी अतिरिक्त बाइट्स/पठन के बीच आंशिक वर्ण कैशिंग) जिम्मेदारी और StreamReader कार्यान्वयन का आंतरिक कार्यान्वयन विवरण है।

using System; 
using System.IO; 
using System.Text; 

class Test 
{ 
    public static void Main() 
    { 
     try 
     { 
      // Create an instance of StreamReader to read from a file. 
      // The using statement also closes the StreamReader. 
      using (StreamReader sr = new StreamReader(
       "TestFile.txt", 
       Encoding.UTF8 
       )) 
      { 
       const int bufferSize = 1000; //could be anything 
       char[] buffer = new char[bufferSize]; 
       // Read from the file until the end of the file is reached. 
       while (bufferSize == sr.Read(buffer, bufferSize, 0)) 
       { 
        //successfuly decoded another buffer's-worth of data 
       } 
      } 
     } 
     catch (Exception e) 
     { 
      // Let the user know what went wrong. 
      Console.WriteLine("The file could not be read:"); 
      Console.WriteLine(e.Message); 
     } 
    } 
} 
+0

@ChrisW, एक छोटी सी बग, पढ़ें (बफर, बफर आकार, 0), पढ़ना चाहिए (बफर, 0, बफर आकार)। :-) एक और मुद्दा यह है कि, मुझे आपकी विधि मिलती है और XMLDocument.Load का उपयोग करके अलग-अलग परिणाम होंगे। अंतर्निहित फ़ाइल (उदा। TestFile.txt) में यूटीएफ -8 के अमान्य बाइट अनुक्रमों के बावजूद आपकी विधि कभी भी कोई अपवाद नहीं फेंक देगी, लेकिन XMLDocument.Load अपवाद फेंक देगा। कृपया मेरी मूल पोस्ट के EDIT1 अनुभाग का संदर्भ लें। क्या गलत है इसका कोई आइडिया? – George2

+1

मुझे नहीं पता (मैं केवल नीचे दिए गए सुझावों को तोते के लिए एक कोड उदाहरण दे रहा था)। आप क्या अपवाद पकड़ रहे हैं? क्या आप जानते हैं (स्वतंत्र रूप से) फ़ाइल में यूटीएफ 8 सही है या नहीं? यदि आप सुनिश्चित हैं कि यह गलत है, और उपरोक्त कोड विफल नहीं हो रहा है, तो जब वे फेंक दिए जाते हैं तो अपवादों को पकड़ने के लिए विजुअल स्टूडियो सेट के साथ कोड चलाने का प्रयास करें, केवल तभी जब वे अनचाहे हों? क्योंकि शायद (हालांकि मुझे नहीं पता क्यों) StreamReader कार्यान्वयन चुपचाप किसी भी एन्कोडिंग अपवाद पकड़ता है। – ChrisW

+0

@ChrisW, मेरे एक्सएमएल फ़ाइल सरल और छोटे,, http://i42.tinypic.com/wioc9c.jpg जब XMLDocument उपयोग कर रहा है सामग्री है।लोड, एक्सएमएल फ़ाइल को अमान्य यूटीएफ -8 एन्कोडिंग के रूप में माना जाएगा, लेकिन आपकी विधि का उपयोग करते समय, इसे वैध एन्कोडिंग के रूप में माना जाएगा - कोई अपवाद नहीं, कोई विचार? – George2

0

क्या यह काम नहीं करेगा?

StreamReader reader = new StreamReader(file); 

Console.WriteLine(reader.CurrentEncoding.ToString()); //You get the default encoding 
reader.Read(); 

Console.WriteLine(reader.CurrentEncoding.ToString()); //You get the right encoding. 
reader.Close(); 

यदि कोई व्यक्ति समझाने में मदद नहीं कर सकता है तो क्यों?

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