我想知道,如果您有一个特别大的文件,例如 64 MB,是否可以找出该文件的物理硬盘位置,然后从特定偏移量读取字节到该文件中?
假设我对距文件开头偏移 60 MB 的 100 个字节感兴趣。如果我使用某些应用程序级别的eek()函数,我不希望从文件开头到文件末尾需要进行数百次磁盘搜索,效率低下。
有解决办法吗?
非常感谢!
答案1
您似乎对seek()
行为方式有误解。它确实尽可能高效地找到存储此偏移量处的数据的位置,而无需读取中间字节。将有几次查找(可能不是数百次)来遍历块索引。
你不能做的是保存从文件打开时到下一次打开时的块索引的遍历。操作系统必须记住该文件自上次打开以来尚未被修改或重新定位,这将需要记住大量数据以获得非常小的潜在收益。
请注意,文件的内容通常不在连续的磁盘位置中。文件往往是碎片化的。文件系统通常会尝试减少碎片,但这通常不能得到保证。
答案2
重读一遍,似乎我没有回答潜在的问题:
在应用程序(实际上是内核)级别使用“查找”并不一定会花费磁盘上的任何“查找” - 它所做的只是更新与文件句柄关联的偏移量。
一旦您要求内核读取或写入,它就会将该偏移量转换为磁盘偏移量,这可能需要读取块来弄清楚,但最好的情况是一次查找成本 - 就像您的直接访问一样。
这样做绝对是可能的:毕竟,这正是文件系统驱动程序所做的事情,因此其他人也一定可以做到。您所需要的只是访问原始磁盘。
那里 是 的 例子人们对现有文件系统格式这样做。如果需要,您也可以手动执行此操作。
如果文件系统处于活跃使用状态,您将面临一些技术挑战,这使得操作变得更加困难 - 因为磁盘上的内容正在以您无法完全看到的方式发生变化 - 但这仍然是可能的。
也可以直接询问内核;这xfs_bmap工具可以做到这一点,并且至少某些文件系统实现了相同的接口,因此您可以直接询问。
不过,计算位置将花费与内核相同的搜索次数,因此您不太可能实际保存任何事物做这个。
答案3
我不这么认为。
如果打开文件,您将位于开头(用于读/写)或结尾(用于追加)。即使在“更新模式”下,您也不会简单地落在文件中间的某个指定位置。
我认为你能做的最好的事情就是你已经逃避的事情:如果你可以计算从一开始的偏移量,你就可以直接寻找该位置并读取数据。我认为这之间不会涉及任何过多的读取操作。打开文件后的下一次读取应该位于计算出的偏移量处。