2011-06-24 20 views
0

我正在尋找一種可靠的方法來重置StreamReader以便開始使用,特別是當他的基礎BaseStream以BOM開頭時,但在沒有BOM時也必須工作。創建一個從流開頭讀取的新StreamReader也是可以接受的。當他的BaseStream具有BOM時,將StreamReader返回到開始

可以使用任何編碼創建原始StreamReader,並將detectEncodingFromByteOrderMarks設置爲true或false。另外,可以在讀取之前或之前沒有調用重置。

流可以是隨機文本,以字節0xef,0xbb,0xbf開頭的文件可以是帶有BOM或以有效字符序列開頭的文件(例如,如果ISO-8859-1編碼是使用),取決於StreamReader創建時使用的參數。

我見過other solutions,但是當BaseStream以BOM開始時,它們不能正常工作。 StreamReader會記住它已經檢測到BOM,並且執行讀取操作時返回的第一個字符是特殊的BOM字符。

此外,我可以創建一個新的StreamReader,但我不知道是否將原始StreamReader創建時detectEncodingFromByteOrderMarks設置爲true或設置爲false。

這是我第一次嘗試:

//fails with TestMethod1 
    void ResetStream1(ref StreamReader sr) { 
     sr.BaseStream.Position = 0; 
     sr.DiscardBufferedData(); 
    } 

    //fails with TestMethod2 
    void ResetStream2(ref StreamReader sr) { 
     sr.BaseStream.Position = 0; 
     sr = new StreamReader(sr.BaseStream, sr.CurrentEncoding, true); 
    } 

    //fails with TestMethod3 
    void ResetStream3(ref StreamReader sr) { 
     sr.BaseStream.Position = 0; 
     sr = new StreamReader(sr.BaseStream, sr.CurrentEncoding, false); 
    } 

而這些都是thest方法:

Stream StreamWithBOM = new MemoryStream(new byte[] {0xef,0xbb,0xbf,(byte)'X'}); 


    [TestMethod] 
    public void TestMethod1() { 
     StreamReader sr=new StreamReader(StreamWithBOM); 
     int before=sr.Read(); //reads X 

     ResetStream(ref sr); 
     int after=sr.Read(); 

     Assert.AreEqual(before, after); 
    } 

    [TestMethod] 
    public void TestMethod2() { 
     StreamReader sr = new StreamReader(StreamWithBOM,Encoding.GetEncoding("ISO-8859-1"),false); 
     int before = sr.Read(); //reads ï 

     ResetStream(ref sr); 
     int after = sr.Read(); 

     Assert.AreEqual(before, after); 
    } 

    [TestMethod] 
    public void TestMethod3() { 
     StreamReader sr = new StreamReader(StreamWithBOM, Encoding.GetEncoding("ISO-8859-1"), true); 
     int expected = (int)'X'; //no Read() done before reset 

     ResetStream(ref sr); 
     int after = sr.Read(); 

     Assert.AreEqual(expected, after); 
    } 

最後,我發現它通過了所有3次測試的解決方案(見我自己的答案) ,但我想看看是否可以採用更加優雅或快速的解決方案。

回答

1
//pass all 3 tests 
    void ResetStream(ref StreamReader sr){ 
     sr.Read(); //ensure that BOM is detected if configured to do so 
     sr.BaseStream.Position=0; 
     sr=new StreamReader(sr.BaseStream, sr.CurrentEncoding, false); 
    } 
+0

是的,但不要經常這樣做。 –

+0

這裏的錯誤是什麼?和@HansPassant爲什麼不呢? – PsychoData

相關問題