【问题标题】:Need help understanding Stream.Read()需要帮助理解 Stream.Read()
【发布时间】:2010-10-19 08:13:00
【问题描述】:

我对逐渐将文件读入缓冲区的步骤有些困惑。

来自 MSDN 文档

public abstract int Read(
    byte[] buffer,
    int offset,
    int count
)

来源C# Examples

FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
try
{
    int length = (int)fileStream.Length;  // get file length
    buffer = new byte[length];            // create buffer
    int count;                            // actual number of bytes read
    int sum = 0;                          // total number of bytes read

    // read until Read method returns 0 (end of the stream has been reached)
    while ((count = fileStream.Read(buffer, sum, length - sum)) > 0)
        sum += count;  // sum is a buffer offset for next reading

我可以说 fileStream.Read(buffer, sum, length - sum) 行读作“fileStreamsum(偏移)到length - sum(要读取的总字节数)读入buffer ”。好的,所以在开始时,当sum = 0 时,我会在 1 内有效地将整个 fileStream 读入缓冲区,但我认为情况并非如此。也许Read() 将任何可能的内容读入缓冲区?然后返回以便您可以再次Read() 吗?我有点困惑。

【问题讨论】:

    标签: c# io filestream


    【解决方案1】:

    Read 将读取任何可用的内容(阻塞直到 something 可用)但可能没有足够的数据准备好填充缓冲区以开始。

    想象一下通过网络下载数据 - 可能有数兆字节的数据要下载,但只有部分数据可供开始使用。所以你需要一直打电话给Read(),直到你想读完为止。

    Stream.Read最多读取您要求的字节数,但可以轻松读取更少。诚然,对于本地文件流,我怀疑它总是按照您的要求读取,除非文件更短,但一般流并非如此,而且我不相信它是 保证本地文件流。

    【讨论】:

    • 嗯,那么不知何故,fileStream.Length 将被设置为实际的总长度?不仅仅是可用的?
    • @jiewmeng:嗯,fileStream.Length 将是您读取长度时的文件长度。该文件可能会在那时和您读取数据之间更改长度。
    • 那我猜它只会增加?我也想知道缓冲区是否与逐步读取文件有关,以便应用程序不会使用太多内存?我对此表示怀疑......只是检查
    • @jlewmeng:这取决于您在共享方面打开文件的方式,其他应用程序是否可以在您阅读文件时截断文件。流数据的想法确实允许您逐步阅读,而无需同时创建所有内容或在内存中。不要只考虑文件级别 - 考虑潜在的无限数据流等。
    • @knocte:这只是 IMO 的糟糕文档。 StreamReader.ReadBlock(这是我假设您所指的)将阻塞,直到 all 已读取请求的数据或到达流的末尾。 Read 将阻塞直到 一些 数据被读取 - 它仍然阻塞。
    【解决方案2】:

    Read 方法将读取至少一个字节,最多读取指定的字节数。

    该方法通常会返回当前可用的所有数据。例如,如果流来自互联网,它通常会返回它已经收到的内容,而对于文件流,它通常会返回整个文件。

    但是,最佳行为是由实现决定的。例如,它可能首先返回它可以从文件缓存中获取的内容,这些内容可以立即返回,然后让您再次调用以获取需要实际磁盘读取的数据。

    在使用Read 方法时,您应该始终使用循环,以便确保获取所有数据。如果第一次调用似乎总是返回所有数据,这似乎没有必要,但在某些情况下它可能不会。

    【讨论】:

    • 向@Jon Skeet 提出的同样问题:不知何故,fileStream.Length 将设置为实际总长度?不仅仅是可用的?
    • 我也想知道缓冲区是否与逐步读取文件有关,以便应用程序不会使用太多内存?我对此表示怀疑......只是检查
    • @jiewmeng:Length 属性将设置为总长度(如果可用)。对于长度未知的流,该属性不可用,并抛出NotSupportedException。是的,这种读取流的方式的原因是它可以逐步读取,要么是因为读取整个文件占用了太多内存,要么是因为整个流还不可用。
    【解决方案3】:

    来自 MSDN:

    When overridden in a derived class, reads a sequence of bytes from the current stream and advances the position within the stream by the number of bytes read.
    
    Return Value
    
    Type: System.Int32
    The total number of bytes read into the buffer. This can be less than the number of bytes requested if that many bytes are not currently available, or zero (0) if the end of the stream has been reached.
    

    【讨论】:

      猜你喜欢
      • 2013-04-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-23
      • 2022-01-15
      • 1970-01-01
      • 2012-09-01
      • 2014-11-25
      相关资源
      最近更新 更多