为什么 System.IO.StreamReader 无法从我的自定义流中读取?
我正在为我的应用程序中的 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
I'm in the process of creating a custom stream for an API endpoint in my app. The stream needs to have custom logic that I don't want to get into, but suffice to say I can't use a built-in stream class.
I did the minimum necessary to implement a read-only stream (inheriting from System.IO.Stream) and I've verified that the System.IO.BinaryReader class can read from my stream:
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)))
The string "contents" contains the correct string for the entire stream.
However, I would like to be able allow the use of the System.IO.StreamReader class:
Dim reader As New System.IO.StreamReader(GenerateStream(business, logic), System.Text.Encoding.ASCII)
Dim contents As String = reader.ReadToEnd
but for whatever reason the ReadToEnd always returns the empty string.
Any ideas?
Here's the stream:
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
仔细查看
StreamReader.ReadToEnd 的描述
显示,引用:它进一步说道:
但是,从底层来看,似乎只有 Stream.Read 被调用,它应该提供您需要的输出。但是,您确实知道 StreamReader 读取字符,它会努力将数据解释为字符串。不确定如果不能的话会发生什么。数据由什么组成?
更新:考虑以下测试代码(抱歉,C#,但使用 一个转换器来获取您的代码),我没有包含抽象类中未实现的方法,以免分散对核心的注意力。正如概念证明一样,这似乎适用于 ASCII 编码,并且无需重新初始化或执行 Seek。
要点是:问题必须出在您实际的读取代码中或您没有向我们展示的业务逻辑中。您选择的方法本身应该很有效。您是否尝试过手动实现“从头到尾”?或者使用
BinaryReader
,使用 ReadBytes(many)`` 读取末尾内容?Looking closely at the description of
StreamReader.ReadToEnd
shows, quote:It further goes on, saying:
But, looking under the hood, only Stream.Read is called, it seems, which should provide the output you need. But, you do know that StreamReader reads characters, it tries hard to interpret the data as a string. Not sure what happens if it cannot. What does the data consist of?
Update: Consider the following test code (sorry, C#, but use a converter to get your code), I did not include the non-implemented methods from the abstract class so as to not distract from the core. Just as a proof of concept, this seems to work with ASCII encoding and without the need to re-init or an implementation for Seek.
Point being: the problem must lie in your actual Read-code or in the business logic you don't show us. The approach you've chosen, on itself, should simply work. Have you tried implementing, by hand, a "read-to-end"? Or with the
BinaryReader
, reading past the end with ReadBytes(many)``?尝试这样做:
同时确保您不想使用的所有方法都会抛出
NotImplementedException
。Try doing this:
Also make sure all the methods you don't want used will throw
NotImplementedException
.