2009-10-07 41 views
1

我正在創建一個System.IO.Stream實現,用於設置HttpContext.Response.Filter的篩選器。我希望知道Write(byte[], int, int)的所有調用是否可以保證寫入的字節包含整個字符字節序列,或者如果單個字符(如果是utf-32編碼)可能會在不同的調用之間進行分割。我可以保證Response.Filter的Stream.Write()方法不會有部分字符字節嗎?

public override void Write(byte[] buffer, int offset, int count) { 
    // Here `e' is a reference to `ctx.Response.ContentEncoding' 
    // from the original context. 
    char[] chars = e.GetChars(buffer, offset, count); 
    //... Stream processing logic here. 
} 

我使用UTF-32電流測試證明,調用似乎總是隻包含整個字符字節序列,但我想確認之前,我驗證了我的假設。

如果正在寫入的字節很可能會在調用Write之間拆分,那麼解決此問題的最佳方法是什麼?我想在我的構造函數中執行單字節寬度檢查,並使用它來查看字節數組是否可以被該值整除。然而,這自然是不受歡迎的,儘管實現起來相當微不足道。

// Here `e' is a reference to `ctx.Response.ContentEncoding' 
// from the original context. 
// `charLen' will yield 4 for a utf-32 encoding. 
charLen = e.GetByteCount(new char[] { ' ' }); 

回答

4

流不知道它們是處理字符數據還是二進制數據。這取決於過濾器或潛在的StreamWriter,它很可能會包裝您的流以決定是否會一次寫出整個角色。

我親自預計StreamWriter只寫出完整的字符,但我不認爲我會依賴它。我看不到任何保證這種行爲的事情。

我建議你使用System.Text.Decoder(通過調用Encoding.GetDecoder獲得)並使用它來保持適當的狀態。事實上,這正是它的設計目的:)查看鏈接的文檔以獲取更多詳細信息。

+0

嗨,喬恩,感謝您的回覆。我以爲Encoding.GetChars是對編碼GetDecoder.GetChars的引用?但我關心的是,如果當前序列中沒有一個字節,但是在下一次調用Write()的第一部分時,我怎麼知道?沒有解碼器可以告訴。如果包裝我的流的流當前只是鏈中的默認流)正在寫入二進制文件,那麼這就是另一個故事,因爲流只處理字符處理。 – 2009-10-07 10:43:23

+0

Encoding.GetChars將創建一個* new *解碼器 - 您希望在兩次調用之間保留一個,這樣如果一次寫入完成一半,它將保留「備用」字節以供下次調用。 – 2009-10-07 10:46:36

+0

(只是爲了澄清 - Encoding.GetChars會*邏輯*創建一個新的解碼器......實現可能實際上不會這樣做,關鍵是編碼不是有狀態的,而解碼器是。) – 2009-10-07 10:47:31

相關問題