我是不是需要将流(C#)重置为开始?

Posted

技术标签:

【中文标题】我是不是需要将流(C#)重置为开始?【英文标题】:Do I need to reset a stream(C#) back to the start?我是否需要将流(C#)重置为开始? 【发布时间】:2010-12-17 07:04:37 【问题描述】:

我不太了解 C# 中的流。现在我有一个流,我放入流阅读器并阅读它。稍后在其他一些方法中我需要读取流(相同的流对象)但是这次我得到了这个错误

System.ArgumentException was unhandled by user code
  Message="Stream was not readable."
  Source="mscorlib"
  StackTrace:
       at System.IO.StreamReader..ctor(Stream stream, Encoding encoding, Boolean detectEncodingFromByteOrderMarks, Int32 bufferSize)
       at System.IO.StreamReader..ctor(Stream stream)
       at ExtractTitle(Stream file) in :line 33
       at GrabWebPage(String webPath) in :line 62
       at lambda_method(ExecutionScope , ControllerBase , Object[] )
       at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters)
       at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
       at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
       at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClassa.<InvokeActionMethodWithFilters>b__7()
       at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation)
  InnerException: 

所以我想也许通过阅读流到最后。然后,当我尝试再次读取它时,它位于流的末尾,这就是我收到此错误的原因。

那么有人可以对此有所了解吗?

谢谢

【问题讨论】:

【参考方案1】:

当你将一个流读到最后,特别是使用StreamReaderReadToEnd 方法,你必须将Seek 读回到开头。可以这样做:

StreamReader sr = new StreamReader(stream);
sr.ReadToEnd();
stream.Seek(0, SeekOrigin.Begin); //StreamReader doesn't have the Seek method, stream does.
sr.ReadToEnd(); // This now works

【讨论】:

这看起来是比仅仅关闭它更好的方法,而且看起来是正确的答案。 +1 StreamReader有seek吗?我找不到它。 否;流确实如此。在上面的代码中将sr.Seek 更改为stream.Seek 稍微简单的语法:stream.Position = 0; @chobo2 可以通过调用StreamReader.BaseStream来调用StreamReader的底层流。【参考方案2】:

你的结论是正确的;到达流的末尾后,您将无法读取更多数据,直到您重置您在流中的位置:

myStream.Position = 0;

这相当于回到起点。请注意,您的流必须支持寻求此功能;并非所有流都可以。您可以使用CanSeek 属性进行检查。

【讨论】:

那么我怎样才能得到一个流呢?就像我试图从 ftp 请求中返回“GetResponseStream()”,这会返回一个“Stream”,它不支持“Seeking”,所以我该怎么办? 你能一口气读完整个流吗?如果是这样,将其读入字节数组,然后从该数组中创建一个新的 MemoryStream(支持查找)。 如何将其读入字节数组?就像我不需要先弄清楚流的大小才能知道如何使字节数组变大吗? 以小块(比如 1024 字节)读取它,然后将该块写入 MemoryStream。 Jon Skeet 写了一个很好的答案:***.com/questions/221925/… 一种更优雅的方法 IMO。【参考方案3】:

BaseStream 用于StreamReader

 StreamReader sr = new StreamReader(pFileStream);
 sr.BaseStream.Seek(0, SeekOrigin.Begin);

【讨论】:

以上是关于我是不是需要将流(C#)重置为开始?的主要内容,如果未能解决你的问题,请参考以下文章

C# dataGridView1 重置背景颜色?

C#/.NET 中不可重置的“标志”线程是不是安全?

vs2008开始设置的用c#环境,现在写c++的代码没有智能提示了,怎么办?

如何重置为提交并使其成为大师?

英特尔实感 C# 将流录制到文件

将熊猫行索引重置为从 0 以外的数字开始?