我想知道一种情况Read(char [],int,int)无法返回请求的所有字符,而ReadBlock()按预期返回所有字符(例如当StreamReader与FileStream对象的实例一起工作时).
Jon*_*nna 15
实际上,当使用StreamReader它时,它很可能只发生一段可能会延迟一段时间的流 - 例如人们在这里提到的网络流.
然而,在一个TextReader普遍,你可以期望它发生在任何时间(与.NET的在目前它没有发生的情况下,未来的版本中可能包括-它不会发生与StreamReader上支持FileStream未记录,所以不能保证将来不会发生这种情况).
特别是在很多情况下,如果只是清空当前缓冲区可以部分地完成调用,那么实现者不会返回请求的数量更容易(通过更简单,更可靠和可能更高效的代码的效果) ,或者TextReader在执行只能返回较少数量字符的操作之前,使用请求的金额作为传递给后备源(流或其他)的金额.
现在,回答关于"何时使用StreamReader.ReadBlock()?"的实际问题.(或者更一般地,何时使用TextReader.ReadBlock()).应牢记以下内容:
双方Read()和ReadBlock()保证,除非整个源已读返回至少一个字符.如果有待处理的内容,也不会返回0.
调用ReadBlock()时Read()会做的是浪费的,因为它可以将不必要的.
但在另一方面,这不是说浪费.
但是第三方面,Read()返回少于请求字符的情况通常是另一个线程参与获取将填充缓冲区以进行下一次调用的内容,或者该内容尚不存在的情况(例如用户输入)或者在另一台机器上的挂起操作) - 在处理部分结果时找到更好的整体并发性,然后Read()在完成时再次调用.
所以.如果你可以用部分结果做一些有用的事情,那就打电话来Read()处理你得到的东西.特别是如果你循环并处理每个的结果Read()然后执行此操作而不是使用ReadBlock().
一个值得注意的案例是,如果您正在构建由另一个人支持的自己的TextReader.ReadBlock()除非算法确实需要一定数量的字符才能工作,所以没有必要调用- 只需从调用中尽可能多地返回,Read()并在需要时调用调用代码ReadBlock().
特别要注意以下代码:
char buffer = char[4096];
int len = 0;
while((len = tr.ReadBlock(buffer, 0 , 4096)) != 0)
DoSomething(buffer, 0, len);
Run Code Online (Sandbox Code Playgroud)
可以改写为:
char buffer = char[4096];
for(int len = tr.Read(buffer, 0, 4096); len != 0; len = tr.Read(buffer, 0, 4096))
DoSomething(buffer, 0, len);
Run Code Online (Sandbox Code Playgroud)
它DoSomething()有时可能会调用较小的大小,但如果为下次调用提供数据时涉及另一个线程,它也可以具有更好的并发性Read().
然而,在大多数情况下,增益并不重要.如果你真的需要一定数量的字符,那就去打电话ReadBlock().最重要的是,在那些与检查它的成本Read()相同的结果的情况下,这是非常轻微的.在特定情况下,不要试图猜测是否安全; 如果它需要保证然后使用.ReadBlock()ReadBlock()Read()ReadBlock()ReadBlock()
Rob*_*obV -1
这是网络流上的一个主要问题,特别是如果流数据非常大并且提供流的服务器将其作为分块输出(即对于 HTTP 来说非常典型),因为一旦Read()EOS 被调用,单个字符读取就会给出 -1。达到时,Read(char[], int, int)带参数的调用将达到要求的字符数,如果达到 EOS,则返回更少的字符数,然后返回读取的字符数,如果达到 EOS,则返回零
而ReadBlock()等待数据从流中可用,因此您永远不会遇到此问题。
另一件需要注意的事情是,这两种形式都会读取最大字符数,并且如果没有那么多可用字符,则不能保证返回那么多字符
我前段时间问了一个类似主题的问题 -从 HttpResponseStream 读取失败- 当我从 HTTP 流读取时遇到问题
| 归档时间: |
|
| 查看次数: |
25070 次 |
| 最近记录: |