我们知道后备存储流(例如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包装)发出3次ReadByte()吗?
答案 0 :(得分:1)
简而言之,否:StreamReader
和FileStream
都不会重复呼叫ReadByte()
。但是,它们确实调用Read(Byte[], Int32, Int32)
,它一次返回多个字节,而不是单个字节。
这与进入C#的深度一样,最终被路由到对Kernel32的ReadFile的调用中,该调用的签名如下所示:
BOOL ReadFile(
HANDLE hFile,
LPVOID lpBuffer,
DWORD nNumberOfBytesToRead,
LPDWORD lpNumberOfBytesRead,
LPOVERLAPPED lpOverlapped
);
要验证这一点,我们可以从StreamReader
的{{3}}开始旅程:
ReadLine()
呼叫StreamReader
的{{3}} ReadBuffer()
调用Stream
的{{3}}方法,鉴于ReadLine method如何创建StreamReader
的方法是ReadBuffer()
。FileStream
的{{3}}调用FileStream
的{{3}}方法。Read(Byte[], Int32, Int32)
调用FileStream
的{{3}}方法。File.OpenText(...)
调用Win32Native
的静态FileStream
方法。Read(...)
method方法调出Kernel32.dll。注意:这是通过查看.NET Framework代码获得的。大概.NET Core代码是等效的,但不完全相同。