目前,C# 中没有 NetworkStream.Peek
方法.实现这种功能与 NetworkStream.ReadByte
类似的方法的最佳方法是什么,除了返回的 byte
实际上并未从 Stream
中删除?
如果不需要实际检索字节,可以参考DataAvailable
属性.
否则,您可以使用StreamReader
并调用它的 Peek
方法.
请注意,由于延迟问题,这两种方法对于从网络流中读取都不是特别可靠.数据可能会在您查看 后立即变得可用(存在于读取缓冲区中).
我不确定你打算用它做什么,但是 NetworkStream
上的 Read
方法是一个阻塞调用,所以你真的不需要检查状态,即使您是分块接收.如果您试图在从流中读取数据时保持应用程序响应,则应改用线程或异步调用来接收数据.
根据这篇文章,StreamReader.Peek
在 NetworkStream
上有问题,或者至少有未记录的行为,所以如果你选择走那条路要小心.
更新 - 回复评论
窥视"实际流本身的概念实际上是不可能的;它只是一个流,一旦接收到字节,它就不再在流上.某些流支持搜索,因此您可以在技术上重新读取该字节,但 NetworkStream
不是其中之一.
偷看仅适用于将流读入缓冲区时;一旦数据位于缓冲区中,那么查看就很容易了,因为您只需检查缓冲区中当前位置的任何内容.这就是 StreamReader
能够做到这一点的原因;没有 Stream
类通常会有自己的 Peek
方法.
现在,对于这个问题,我质疑这是否真的是正确答案.我理解动态选择处理流的方法的想法,但是您真的需要在原始流上执行此操作吗?你能不能先把流读入一个字节数组,或者甚至将它复制到一个MemoryStream
,然后从那一刻开始处理它?</p>
我看到的主要问题是,如果在您从网络流中读取数据时发生不好的事情,数据就会消失.但是如果你先把它读到一个临时位置,你可以调试它.您可以找出数据是什么以及为什么试图处理数据的对象中途失败.
通常,您想要对 NetworkStream
做的第一件事就是将其读入本地缓冲区.我能想到的不这样做的唯一原因是,如果您正在读取大量数据——即便如此,如果文件系统不适合内存,我可能会考虑将其用作中间缓冲区.
我不知道您的确切要求,但根据我目前所了解的,我的建议是:不要尝试直接从 NetworkStream
处理您的数据,除非有这样做的令人信服的理由.考虑先将数据读入内存或磁盘,然后处理副本.
Currently, there isn't a NetworkStream.Peek
method in C#. What is the best way of implementing such a method which functions just like NetworkStream.ReadByte
except that the returned byte
is not actually removed from the Stream
?
If you don't need to actually retrieve the byte, you can refer to the DataAvailable
property.
Otherwise, you can wrap it with a StreamReader
and invoke its Peek
method.
Note that neither of these are particularly reliable for reading from a network stream, due to latency issues. The data might become available (present in the read buffer) the very instant after you peek.
I'm not sure what it is that you intend to do with this, but the Read
method on NetworkStream
is a blocking call, so you don't really need to check for status, even if you are receiving in chunks. If you are trying to keep the application responsive while reading from the stream, you should use a thread or asynchronous call to receive the data instead.
Edit: According to this post, StreamReader.Peek
is buggy on a NetworkStream
, or at least has undocumented behaviour, so be careful if you choose to go that route.
Updated - response to comments
The notion of a "peek" on the actual stream itself is actually impossible; it's just a stream, and once the byte is received then it is no longer on the stream. Some streams support seeking so you could technically re-read that byte, but NetworkStream
isn't one of them.
Peeking only applies when are reading the stream into a buffer; once the data is in a buffer then peeking is easy because you just check whatever's at the current position in the buffer. That's why a StreamReader
is able to do this; no Stream
class will generally have its own Peek
method.
Now, for this problem specifically, I question whether or not this is really the right answer. I understand the idea of dynamically selecting a method for processing the stream, but do you really need to do this on the raw stream? Can you not read the stream into a byte array first, or even copy it into a MemoryStream
, and process it from that point on?
The main issue I see is that if something bad happens when you're reading from a network stream, the data is gone. But if you read it into a temporary location first, you can debug this. You can find out what the data was and why the object that was trying to process the data failed halfway through.
In general, the very first thing you want to do with a NetworkStream
is read it into a local buffer. The only reason I can think of not to do this is if you're reading an enormous amount of data - and even then, I might consider using the file system as an intermediate buffer if it won't fit in memory.
I don't know your exact requirements, but from what I've learned so far, my advice would be: Don't try to process your data directly from the NetworkStream
unless there is a compelling reason to do so. Consider reading the data into memory or onto disk first, then processing the copy.
这篇关于C#:实现 NetworkStream.Peek?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!