当我调用fseek()时,在低级别会发生什么?

时间:2015-06-15 22:09:22

标签: file-io ntfs hard-drive

当在C中调用fseek()时,或者在Python或Go等任何现代语言的文件对象上调用seek() - 在非常低的级别会发生什么?

操作系统或硬盘实际上做了什么? 读什么? 会产生什么开销? 块大小如何影响此开销?

编辑以添加:

鉴于NTFS的块大小为4KB,寻求4096字节的IO开销是否比读取4096字节少?

第二次修改:

如有疑问,请进行实证。

使用一些带有1.5GB文件的天真Python代码:

按顺序阅读4096:21.2
寻求4096(相对):1.35
寻求4096(绝对):0.75(有趣)
寻求和阅读每三分之一4096(相对):21.3
寻求和阅读每三分之一4096(绝对):21.5

平均时间以秒为单位。硬件是一台不起眼的PC,带有运行Windows XP的SATA驱动器。

这非常令人失望。我有几GB的文件,我必须在接近连续的基础上阅读。文件中大约66%的4KB块是无趣的,我提前知道它们的偏移量。

最初,我认为重写遗留代码可能是一个大赢家,因为它现在通过文件一次读取4096个字节。假设Win32 Python没有以某种基本方式被破坏,合并搜索对于非随机读取没有任何优势。

1 个答案:

答案 0 :(得分:0)

这在很大程度上取决于当前的情况。通常,fseek()仅更改流的状态(设置当前位置,或者如果参数错误则返回错误)。但是 - fseek()刷新缓冲区,可能会导致挂起的写入操作。如果file是UTF8文件并且启用了转换,则从fseek()调用的ftell()需要读取文件的该部分以正确计算偏移量。如果启用了CRLF转换,则还会导致读取操作。但是在普通二进制文件且没有挂起写操作的情况下,fseek()只是在流中设置位置而不需要转到较低级别。有关更多详细信息,请参阅CRT的源代码。