每个 fread / fwrite 有多少次随机/顺序访问?

lab*_*irc 3 c++ fread

我有以下关于 C 文件 I/O 的问题。

在物理层面(硬盘驱动器),假设每个fread(n_blocks, size, length,FILE fp)操作都应该花费对第一页(块)的一次随机访问和对同一缓冲区的下一个块的 n-1 次顺序访问是否有效?

我之所以这样假设,是因为操作系统有如此多的进程,大多数情况下可以确定其中一个进程也在每个本地程序之间写入或读取文件,fread并且通过该假设,硬盘驱动器位于另一个扇区/柱面。

这个假设可以吗?

ybu*_*ill 5

无论你是否这么认为,这都是对现实的过度简单化。

首先,您似乎认为第三个参数(length)对应于一些离散“访问操作”的数量。不是这种情况。所做的只是fread读取size*length字节;因此,只要乘法不溢出,以下三个调用就会执行完全相同的操作:

fread(n_blocks, size, length, fp);
fread(n_blocks, size*length, 1, fp);
fread(n_blocks, 1, size*length, fp);
Run Code Online (Sandbox Code Playgroud)

实际发生的情况是,将从进程fread/fwrite内存中的内部缓冲区读取和写入。该缓冲区可以通过函数进行控制。当缓冲区满/空时,它们会将读/写转发给操作系统setbuf/setvbuf操作系统有自己的文件缓存。如果您正在读取并且操作系统在缓存中找不到该文件的部分,那么您的程序将等待,直到实际从驱动器中获取数据。写入时,数据将被复制到操作系统缓存并驻留在那里,直到操作系统决定将其写入驱动器,这可能会在程序关闭文件并存在很久之后发生。反过来,今天的硬盘驱动器有自己的内部缓存,操作系统甚至可能不知道这些缓存。

出于所有实际目的,您不应该关心每个fread/fwrite调用访问了多少个驱动器。只需知道 C、操作系统和底层硬件将尽最大努力尽快提供所请求的数据。但是,请记住,整个堆栈针对顺序访问进行了优化。fseek因此,请避免无缘无故地在文件中跳转。