2010-01-26 99 views
1

我正在爲我的應用程序中的API端點創建自定義流。該流需要具有我不想進入的自定義邏輯,但足以說我不能使用內置流類。爲什麼System.IO.StreamReader不能從我的自定義流中讀取?

我做了必要的最低限度,以實現一個只讀流(從System.IO.Stream繼承),我已經驗證了System.IO.BinaryReader類可以從我的流讀取:

Dim reader As New System.IO.BinaryReader(GenerateStream(business, logic)) 
Dim enc As New System.Text.ASCIIEncoding 
Dim contents As String = enc.GetString(reader.ReadBytes(CType(reader.BaseStream.Length, Int32))) 

字符串「contents」包含整個流的正確字符串。

不過,我想能夠允許使用System.IO.StreamReader類的:

Dim reader As New System.IO.StreamReader(GenerateStream(business, logic), System.Text.Encoding.ASCII) 
Dim contents As String = reader.ReadToEnd 

但無論什麼原因,總是ReadToEnd的返回空字符串。

任何想法?

這裏的流:

Public Overrides ReadOnly Property CanRead() As Boolean 
    Get 
    Return True 
    End Get 
    End Property 

    Public Overrides ReadOnly Property CanSeek() As Boolean 
    Get 
    Return False 
    End Get 
    End Property 

    Public Overrides ReadOnly Property CanWrite() As Boolean 
    Get 
    Return False 
    End Get 
    End Property 

    Public Overrides Sub Flush() 
    'this method intentionally left blank' 
    End Sub 

    Public Overrides ReadOnly Property Length() As Long 
    Get 
    Return 'some business logic' 
    End Get 
    End Property 

    Public Overrides Property Position() As Long 
    Get 
    Return bytePosition 
    End Get 
    Set(ByVal value As Long) 
    Throw New System.NotSupportedException 
    End Set 
    End Property 

    Public Overrides Function Read(ByVal buffer() As Byte, ByVal offset As Integer, ByVal count As Integer) As Integer 
    'I return 0 on an end of stream, otherwise the # of bytes successfully read.' 
    End Function 

    Public Overrides Function Seek(ByVal offset As Long, ByVal origin As System.IO.SeekOrigin) As Long 
    Throw New System.NotSupportedException 
    End Function 

    Public Overrides Sub SetLength(ByVal value As Long) 
    Throw New System.NotSupportedException() 
    End Sub 

    Public Overrides Sub Write(ByVal buffer() As Byte, ByVal offset As Integer, ByVal count As Integer) 
    Throw New System.NotSupportedException() 
    End Sub 

回答

2

仔細觀察,報價:

如果 流中的初始位置不明或者該流不 不支持查找,底層 Stream對象也需要 重新初始化。

它進一步推移,他說:

爲了避免這種情況,生產 健壯的代碼,你應該使用Read 方法和 存儲讀取字符預分配的緩衝區。

但是,引擎蓋下看,只有Stream.Read叫,看來,這提供您所需的輸出。但是,您確實知道StreamReader讀取字符,它會盡力將數據解釋爲字符串。不確定會發生什麼,如果它不能。數據由什麼組成?


更新:請看下面的測試代碼(對不起,C#,而是使用a converter讓你的代碼),我不包括從抽象類非實現的方法,以便不分散從核心。就像一個概念證明一樣,這似乎可以用ASCII編碼工作,而無需重新初始化或Seek實現。

public class AsciiStream : Stream 
{ 
    private string dataStream = "abcdefghijklmnopqrstuvwxyz"; 
    private long position = 0; 

    public override bool CanRead 
    { 
     get { return true; } 
    } 

    public override bool CanSeek 
    { 
     get { return false; } 
    } 

    public override bool CanWrite 
    { 
     get { return false; } 
    } 


    public override long Length 
    { 
     get { return dataStream.Length; } 
    } 

    public override long Position 
    { 
     get 
     { 
      return position; 
     } 
     set 
     { 
      position = value < this.Length ? value : this.Length; 
     } 
    } 

    public override int Read(byte[] buffer, int offset, int count) 
    { 
     long bufferPos = offset; 
     long max = this.position + count; 
     max = max < this.Length ? max : this.Length; 
     for (; this.position < max; this.position++) 
     { 
      buffer[bufferPos] = Convert.ToByte(this.dataStream[(int) this.position]); 
      bufferPos++; 
     } 

     return (int) bufferPos - offset; 
    } 
} 


// call the code like as follows: 
StreamReader sReader = new StreamReader(new AsciiStream(), Encoding.ASCII); 
string sToEnd = sReader.ReadToEnd(); 

要點:問題必須存在於您的實際讀取代碼或業務邏輯中,而您並未向我們展示。你選擇的方法本身應該簡單地工作。您是否嘗試過實施「讀取至終止」?或者與BinaryReader一起閱讀ReadBytes(很多)?

+0

數據是字符(在這種情況下用ascii編碼)。我沒有試過用BinaryReader讀取流的結尾,但是我已經驗證了你可以用BinaryReader讀/結束,並且你得到正確的輸出。 雖然也許如果我實現尋求問題將會消失。儘管我確實錯過了「ReadToEnd」的描述。如果尋求解決問題,這是答案。 問題中顯示ReadToEnd的BinaryReader實現。 – 2010-01-26 15:43:59

+0

問題確實存在於我的閱讀方法中。如果/ current/read達到流的末尾,我的讀取方法將返回0。現在只有在從空流讀取時才返回0。 – 2010-01-27 19:19:42

+0

不,尋求或不尋求不是問題。正如你發現的那樣,你的接口實現必須是正確的。如果沒有看到所有相關的代碼,就很難找到這樣的錯誤......;) – Abel 2010-01-28 02:03:43

0

試着這樣做:

Dim reader As New System.IO.StreamReader(
    GenerateStream(business, logic), 
    System.Text.Encoding.ASCII, 
    False 
) 
Dim contents As String = reader.ReadToEnd 

同時確保所有你不想使用將拋出NotImplementedException方法。在StreamReader.ReadToEnd展示說明

+0

他們拋出NotSupportedExceptions,像System.IO.Stream警告會發生。你確定你不是指NotSupportedException而不是NotImplementedException? – 2010-01-26 15:46:36

+0

@Evan - 這其實並不重要。我推薦這個的原因是因爲如果Stream Reader調用這些方法期望發生某些事情,它會拋出並因此使您的調試變得更加容易。 – ChaosPandion 2010-01-26 15:52:37

相關問題