根据cplusplus:
size_t fread(void * ptr,size_t size,size_t count,FILE * stream);
从流中读取一个count元素数组,每个元素的大小为字节大小,并将它们存储在ptr指定的内存块中.
Q1)因此,再次fread读取文件1个字节,所以它不是以1字节方法读取的方式吗?
Q2)结果证明,仍然可以花费更少的时间.
从here开始:
I ran this with a file of approximately 44 megabytes as input. When compiled with VC++2012,I got the following results:
using getc Count: 400000 Time: 2.034
using fread Count: 400000 Time: 0.257
SO上的帖子也很少谈论它取决于操作系统.
Q3)操作系统的作用是什么?
为什么会如此以及幕后背后到底是什么?
解决方法
fread将尝试一次读取的字节数高度依赖于您的C实现和底层文件系统.除非你非常熟悉两者,否则通常可以安全地假设fread将比你自己发明的任何东西更接近最优.
编辑:物理磁盘与其吞吐量相比往往具有相对较高的寻道时间.换句话说,他们开始阅读需要相对较长的时间.但是一旦启动,它们可以相对快速地读取连续的字节.因此,如果没有任何OS /文件系统支持,任何对fread的调用都会导致开始每次读取的严重开销.因此,为了有效地利用磁盘,您需要尽可能多地读取多个字节.但是与cpu,RAM和物理缓存相比,磁盘速度很慢.一次读取太多意味着你的程序花了很多时间等待磁盘完成读取,当它本来可以做一些有用的事情(比如处理已经读取的字节).
这就是操作系统/文件系统的用武之地.从事这些工作的智能人员花费了大量时间来确定从磁盘请求的正确字节数.因此,当您调用fread并请求X字节时,OS /文件系统会将其转换为每个Y字节的N个请求.其中Y是一些通常最佳的值,它取决于比这里提到的更多的变量.
OS /文件系统的另一个角色是所谓的“readahead”.基本思想是大多数IO发生在循环内部.因此,如果一个程序从磁盘请求一些字节,那么它很有可能在不久之后请求下一个字节.因此,操作系统/文件系统通常会比您实际请求的读取次数略多.同样,确切的数量取决于要提及的太多变量.但基本上,这就是为什么一次读取一个字节仍然有些效率(如果没有预读的话,它会再慢10倍).
最后,最好将fread视为给操作系统/文件系统提供一些关于你想要读取多少字节的提示.这些提示越准确(越接近您想要读取的总字节数),OS /文件系统将优化磁盘IO越好.