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

时间:2016-03-31 10:43:40

标签: c c99 stdio

虽然我理解fpos_t是一个意图由fgetpos()函数初始化的opaque类型,C99 rationale的§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基本原理?

1 个答案:

答案 0 :(得分:0)

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

例如,如果long有32位,则可以将其分为记录索引的25位和记录中位置的7位(允许最大可用记录长度为127,并且2 ^ 25~ = 33k记录)。但是,系统可能会允许更多和更大的记录。

(以上陈述部分含糊不清的回忆,部分来自理论文本的推论)。

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

  

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

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