【问题标题】:stream adapters and backing store streams流适配器和后备存储流
【发布时间】:2019-07-10 05:03:55
【问题描述】:

我们知道像 FileStream 这样的后备存储流专门处理字节,因此我们需要流适配器来包装后备存储流。

假设我们使用 StreamReader:

// the data.txt only contains 3 chars in one line
using (StreamReader r = File.OpenText("data.txt"))
{
  string input = null;
  while ((input = r.ReadLine()) != null)
  {
     ...
  }
}

我可以说即使 StreamReader r 只发出 ReadLine() 一次,底层有一个 FileStream xxx(由 StreamReader 包装)发出 ReadByte() 3 次?

【问题讨论】:

  • 您可以通过reading the code 准确了解它的工作原理。 ReadBuffer() 在这里。
  • 最终它似乎通过hereherehere 结束了here
  • @John 感谢您的链接,但我不是高级开发人员,您能告诉我,就我而言,StreamReader 的 ReadLine() 是否会触发多个 FileStream 的 ReadByte()?跨度>
  • 不,它没有。
  • @John 你能看看这个问题吗? stackoverflow.com/questions/57050919/…

标签: c# .net


【解决方案1】:

简而言之,不:StreamReaderFileStream 都不会重复调用 ReadByte()。他们确实这样做了,但是调用 Read(Byte[], Int32, Int32),它一次返回多个字节而不是一个字节。

这与它在 C# 中的深度差不多,因为它最终会被路由到对 Kernel32 的 ReadFile 的调用,其签名如下所示:

BOOL ReadFile(
  HANDLE       hFile,
  LPVOID       lpBuffer,
  DWORD        nNumberOfBytesToRead,
  LPDWORD      lpNumberOfBytesRead,
  LPOVERLAPPED lpOverlapped
);

为了验证这一点,我们可以从StreamReaderReadLine method 开始旅程:

注意:这是通过查看 .NET Framework 代码得出的。大概 .NET Core 代码是等价的,但并不完全相同。

【讨论】:

  • 感谢您的详细解答。调用 FileStream 的 Read(...) 方法,这就是我一直在寻找的答案。另一个问题是关于阅读 frim Stream 时的短计数,我的教科书说我需要做一个“while loop read”。这是否仅适用于指定的流,例如网络流,从永远不会有短计数问题的 FileStream 读取时,我不需要执行 while 循环读取?我正确吗?
  • @slowjams 如果您位于 10128 字节文件的第 10000 字节并且您请求读取 8192 字节,则使用 FileStream 可能会获得更少的字节。使用Read 时,您应该一直阅读,直到您a) 已经拥有所需的所有数据,或b) Read 返回0 字节。 ReadLine in StreamReader 为你包装了这个逻辑,所以你不必担心。请注意,如果没有更多数据要读取,ReadLine 将返回 null
  • @slowjams 你只能知道你是否知道你总共阅读了多少,以及Stream 的完整长度(仅当 Stream 的 CanSeek 属性为 @987654370 时才可用@)。最佳做法是读取直到返回的int 为 0。
  • @slowjams 我认为我们是从不同的角度来解决这个问题的。据我所知,是的,您的逻辑适用于FileStream。我的建议是针对一般情况编写代码,以免您决定一两年后进行一些重构,将方法更改为采用Stream,然后突然遇到可能难以追踪的奇怪错误并解释。
  • returned sum is 500, I know I can stop now. 不,你不能@slowjams。 不要依赖当前的实现。正如我在您的另一个问题中指出的那样,文档对此非常清楚。根据文档,发出另一次读取的开销很小,并且是必需的。所以就去做吧,注意安全。
猜你喜欢
  • 2019-11-18
  • 2015-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多