需要帮助理解Stream.Read()

问题描述:

我对将文件逐步读入缓冲区的步骤有点困惑。需要帮助理解Stream.Read()

从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 

源I可以说,线fileStream.Read(buffer, sum, length - sum)为“fileStreamsum(偏移)到length - sum(总字节读取读入)到buffer“。 OK,所以在开始时,sum = 0时,我将在1短时间内有效地将整个fileStream读入缓冲区,但我认为情况并非如此。也许Read()读取任何它可能会进入缓冲区?然后返回,以便你可以Read()它呢?我有点困惑。

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

想象一下通过网络下载数据 - 可能要下载数兆字节的数据,但只有部分数据可用于下载。所以你需要继续拨打Read(),直到你阅读完你想要的内容。

Stream.Read会读取最多您要求的字节数,但可以轻松读取更少。无可否认,对于本地文件流,我怀疑它总是按照你所要求的读取,除非文件较短,但是对于一般的流不是这样,我认为即使对本地文件流也是如此保证

+0

嗯,那么'fileStream.Length'会被设置为实际的总长度吗?不只是有什么可用的? – 2010-10-19 08:59:47

+0

@jiewmeng:那么,'fileStream.Length'将是您读取该长度时文件的长度。该文件可能会改变之间的时间和你读数据的时间。 – 2010-10-19 09:06:56

+0

那么我猜它只会增加?我还想知道缓冲区是如何逐步读取文件的,以便应用程序不会使用太多内存?我怀疑这是...只是检查 – 2010-10-19 09:21:35

从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. 

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

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

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

使用Read方法时,应始终使用循环,以确保获取所有数据。如果第一个调用看起来总是返回所有数据,但似乎并不是必须的,但可能会出现这种情况。

+0

对@Jon Skeet提出了同样的问题:不知何故,'fileStream.Length'将被设置为实际的总长度?不只是有什么可用的? – 2010-10-19 09:00:22

+0

我还想知道缓冲区是否与逐步读取文件有关,以便应用程序不会使用太多的内存?我怀疑它tho ...只是检查 – 2010-10-19 09:20:38

+0

@jiewmeng:如果可用,'Length'属性将被设置为总长度。对于长度未知的流,该属性不可用,并抛出'NotSupportedException'。是的,读取流的这种方式的原因是它可以逐步读取,因为读取整个文件使用的内存太多,或者因为整个流尚不可用。 – Guffa 2010-10-19 09:33:12