1

アプリで API エンドポイントのカスタム ストリームを作成中です。ストリームには、入りたくないカスタム ロジックが必要ですが、組み込みのストリーム クラスは使用できないと言えば十分です。

読み取り専用ストリーム (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
4

2 に答える 2

2

ショーの説明をよく見てStreamReader.ReadToEnd、引用します。

ストリーム内の初期位置が不明な場合、またはストリームがシークをサポートしていない場合は、基になる Stream オブジェクトも再初期化する必要があります。

さらに、次のように続けています。

このような状況を回避して堅牢なコードを生成するには、Read メソッドを使用して、読み取った文字を事前に割り当てられたバッファーに格納する必要があります。

しかし、ボンネットの下を見ると、必要な出力を提供する必要があるStream.Read のみが呼び出されているようです。しかし、StreamReader が文字を読み取ることは知っていますが、データを文字列として解釈しようとはしません。できない場合はどうなるかわかりません。データは何で構成されていますか?


更新: 次のテスト コードを検討してください (申し訳ありませんが、C# ですが、コンバーターを使用してコードを取得してください)。コアから気を散らさないように、抽象クラスから実装されていないメソッドを含めませんでした。概念実証として、これは 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();

要点: 問題は、実際の読み取りコードまたは表示されていないビジネス ロジックにあるに違いありません。選択したアプローチは、それ自体でうまくいくはずです。「読み取りから終了まで」を手動で実装してみましたか? または、BinaryReaderReadBytes(many)`` で最後を過ぎて読む?

于 2010-01-26T01:00:35.287 に答える
0

これを試してください:

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

また、使用したくないすべてのメソッドがスローされることを確認してくださいNotImplementedException

于 2010-01-26T00:52:04.597 に答える