如果我们在读取时设置缓冲区大小,为什么在FileStream构造函数中需要设置它?

4

FileStream Constructor的文档没有提到原因。它只是说:

bufferSize

类型:System.Int32

一个大于0的正整数,表示缓冲区大小。默认缓冲区大小为4096。

但后来我们使用了一些方法,比如Read,在这些方法中,我们指定了缓冲区大小并提供了缓冲区本身。

那么为什么要在构造函数中指定缓冲区大小呢?

1个回答

6

这些是不同的缓冲区。一个是FileStream自身的内部缓冲区(你在构造函数中传递的大小),另一个是调用者的缓冲区(来自Read方法)。它们之间没有关联。

假设你在构造函数中传递了4000作为内部缓冲区的大小,然后调用:

Read(buffer, 0, 100);

简单来说,假设是首次从这个流中读取,FileStream会去读取文件中的4000字节并将其存储在内部缓冲区中。然后它会向调用者的缓冲区写入100字节。

如果您执行

Read(buffer, 0, 8000)

程序会从文件中读取4000个字节到内部缓冲区,将这4000个字节写入调用者的缓冲区,然后再继续从文件中读取下一个4000个字节到内部缓冲区,完成向调用者缓冲区的写入。

为什么需要内部缓冲区?因为每次进行小规模的读取都会消耗很多资源。比如,如果你按字节逐个读取FileStream流中的4000个字节,它只会通过一次文件系统操作,然后剩余的3999个字节将从内部缓冲区返回。


谢谢。+1。那么如果读取缓冲区比构造函数大会发生什么? - ispiro
作为实现细节,内部缓冲区也可以由操作系统处理,在打开文件句柄时简单地传递大小即可。 - Marc Gravell
@MarcGravell,我不理解你的评论。你是在说构造函数的缓冲区大小可能会被忽略吗? - ispiro
@ispiro 更新了答案。这当然是高级描述,以帮助理解。至于Marc的评论-他的意思是(我认为)FileStream可能没有真正的缓冲区本身(即byte []),而是由操作系统处理。但大小不被忽略-当您开始读取文件时,它会传递给操作系统,并且操作系统将使用此大小作为其缓冲区。因此,您要求FileStream提供100个字节-它要求操作系统提供100个字节-操作系统内部读取4000个字节,但仅返回100个字节,依此类推。 - Evk
@ispiro 不,我的意思是它可能与 FileStream 代码无关,而是与更低级别有关 - 相同的结果,不同的实现。 - Marc Gravell
@MarcGravell 谢谢您澄清这个问题! - ispiro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接