【问题标题】:How can `fsetpos()` be used to "allow random access on files that are too large to handle with `fseek()`?"`fsetpos()` 如何用于“允许随机访问太大而无法使用 `fseek()` 处理的文件?”
【发布时间】:2016-03-31 10:43:40
【问题描述】:

虽然我知道fpos_t 是一种不透明类型,旨在由fgetpos() 函数初始化,但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 的基本原理吗?

【问题讨论】:

    标签: c c99 stdio


    【解决方案1】:

    我相信在某些(可能是 archaic 大型机)系统上,文本文件存储为一系列“记录”(行),因此文件位置由记录索引和位置组成记录,这就是理由文本似乎所指的内容。在操作系统层面,seek 操作需要记录索引和记录内的位置,而不是文件内的字节位置;这会导致记录索引和位置都必须在long 值内编码,以便与fseekftell 一起使用。因此,库实现需要为每个记录索引和位置分配一定数量的位,这限制了记录的数量和位置。

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

    (以上陈述部分是模糊的回忆,部分是从基本原理文本中推断出来的)。

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

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

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

    【讨论】:

    猜你喜欢
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-30
    • 2017-05-15
    • 1970-01-01
    • 2021-07-21
    • 2013-06-11
    相关资源
    最近更新 更多