如何使用`fsetpos()`"允许随机访问文件,这些文件太大而无法用`fseek()`处理?"

gw0*_*gw0 6 c stdio c99

虽然我理解这fpos_t是一个意图由fgetpos()函数初始化的opaque类型,但C99基本原理的 §7.19.9.1 规定:

fgetposfsetpos加入到C89以允许太大处理与文件随机访问操作fseekftell.

和§7.19.9.2:

在一个编码的记录内都记录位置和位置的需要long值可以约束的在其文本文件的大小fseekftell可用于为比二进制文件的大小相当小.

...

fgetposfsetpos加入应对太大处理与文件fseekftell.

这似乎主要集中在文本文件(使用mode排除b标志打开的文件),因为某些实现可能需要存储两个位置(文件记录位置和记录字符位置),这可能会显着减少fseek()和的ftell()功能的有效范围文本流.

尽管如此,我对于文本流如何特别有用我一无所知,我当然不明白它如何有效地用于"随机访问".

似乎实际利用这些函数的唯一方法是通过读取文件的每个字符并缓存它们的fgetpos()d fpos_t值,这似乎充其量只是利基,因为你几乎肯定不想读取LONG_MAX字符附近的任何地方.

什么是"委员会"的想法?有没有C99基本原理?

dav*_*mac 0

我相信在某些(可能是古老的大型机)系统上,文本文件存储为一系列“记录”(行),因此文件位置由记录索引和记录内的位置组成,这就是基本原理文本的内容来指代。在操作系统级别,查找操作需要记录索引和记录内的位置,而不是文件内的字节位置;这导致了这样的问题:记录索引和位置都必须编码在与和 一起long使用的值中。因此,库实现需要为每个记录索引和位置分配一定数量的位,这限制了记录的数量和位置。fseekftell

例如,如果long有 32 位,则可以将其分为 25 位用于记录索引,7 位用于记录内的位置(允许最大可用记录长度为 127,以及 2^25 ~= 33k 记录)。然而,系统可以允许比这更多和更大的记录。

(以上陈述部分是模糊的回忆,部分是根据理据文本的推论)。

fseek然而,即使在现代桌面系统上,真正的问题ftell是一个long值可能不足以代表文件位置的全部范围。在 32 位系统上long通常为 32 位,但文件通常仍会增长到大于 2GB。因此,需要一种不同的机制来指定文件偏移量。

我当然不明白它如何有效地用于“随机访问”。

在这种情况下,通过“随机访问”,他们所说的是寻找已经访问过的任何点的能力,也就是说,您可以重新定位(使用fsetpos)您已经获得(通过fgetpos)的任何位置。它不是寻找任意字节位置。可以说“随机访问”是一个错误的术语,但我认为他们只是想与纯粹的顺序访问区分开来。