【发布时间】:2019-11-19 13:56:41
【问题描述】:
我的课本上说:
Read 从流中接收一个数据块到一个数组中。它返回的数量 接收到的字节数,总是小于或等于 count 参数。如果 它小于计数,这意味着要么已经到达流的末尾,要么 流以较小的块为您提供数据(通常是网络流的情况)。在任何一种情况下,数组中的字节余额都将保持未写入状态,它们之前的值将被保留。 使用 Read,您可以确定您已经到达终点 仅当方法返回 0 时才流式传输。因此,如果您有 1000字节流,下面的代码可能读不全 进入记忆:
// Assuming s is a stream:
byte[] data = new byte [1000];
s.Read (data, 0, data.Length);
Read 方法可以读取 1 到 1,000 个字节的任意位置, 保持流的余额未读。
我很困惑,我写了一个简单的 concolse 应用程序来验证:
//read.txt only contains 3 chars: abc
using (FileStream s = new FileStream("read.txt", FileMode.Open))
{
byte[] data = new byte[5];
int num = s.Read(data, 0, data.Length);
foreach (byte b in data)
{
Console.WriteLine(b);
}
}
输出是:
97
98
99
0
0
所以数据数组已经写入了,为什么教科书上说“数组中字节的余额会保持未写入,可能无法全部读入内存”,
编辑:请丢弃我以前的控制台应用程序,我真正的问题是:
一个文件有 1000 个字节,我请求读取所有 1000 个字节:
byte[] data = new byte [1000];
s.Read (data, 0, data.Length);
为什么它可能无法将其全部读入内存?并且教科书还提供了读取全部1000字节的正确方法:
byte[] data = new byte [1000];
int bytesRead = 0;
int chunkSize = 1;
while (bytesRead < data.Length && chunkSize > 0)
bytesRead +=
chunkSize = s.Read (data, bytesRead, data.Length - bytesRead);
【问题讨论】:
-
你可以注意到
s.Read返回一个整数——读取的字节数 -
斯坦是正确的。大多数粗体文本 (
It returns) 都引用了num。总而言之,这意味着'如果您要求读取 1000 个字节,您将获得最多 1000 个字节 - 如果文件 > 1000 个字节,您将无法获得整个文件,并且您如果文件小于 1000 字节,则将获得小于 1000 字节的数据。这就是 bold 文本的关键所在。当它谈到balance of bytes时,它意味着你看到的那些0。查看它们如何为 0(默认值)。这实际上是不成文的。该数据并非来自文件。 -
如果您在流上调用
Read,则不能保证您可以立即从流中读取所有字节(实际上在大多数情况下您不能)。读取的字节数可能小于缓冲区大小,使缓冲区的其余部分未写入(在您的情况下,数组中的尾随零)。因此,您应该通过循环读取的字节来提前读取起点。 -
stackoverflow.com/questions/3966389/… 可能值得一读@slowjams。
-
@slowjams 因为
Read可以一次只读取一个字节。这将是其他派生类对Stream.Read的完全有效的实现 - 尝试接口/抽象类的一种实现不会立即显示所有其他实现的行为方式。