为什么C ++标准会处理文件查找方式?

时间:2019-12-13 19:47:44

标签: c++ file language-lawyer seek c++20

C ++使用streamoff类型表示(文件)流中的偏移量,并在[stream.types]中定义如下:

  

using streamoff = implementation-defined ;

     

streamoff类型是已签名的基本整数类型之一的同义词,该基本整数类型的大小足以表示操作系统的最大可能文件大小。 287)

     

287)通常很长很长。

这很有意义,因为它允许在大文件中查找(与使用long(可能只有32位宽)相反)。

[filebuf.virtuals]定义了basic_filebuf的在文件中进行搜索的功能,如下所示:

  

pos_type seekoff(off_type off, ios_base::seekdir way, ios_base::openmode which = ios_base::in | ios_base::out) override;

off_type等效于streamoff,请参见[iostreams.limits.pos]。但是,该标准随后继续说明了该功能的作用。最后一句话让我很生气,这需要调用fseek

  

效果:让width代表a_codecvt.encoding()。如果为is_open() == falseoff != 0 && width <= 0,则定位操作失败。否则,如果为way != basic_ios::curoff != 0,并且   如果输出了最后一个操作,则更新输出序列并写入所有未移位序列。   接下来,寻找新位置:如果width > 0,请致电fseek(file, width * off, whence),否则   致电fseek(file, 0, whence)

fseek接受一个long参数。如果off_typestreamoff被定义为long long(如标准所建议),则在调用long时可能导致向下转换为fseek(file, width * off, whence)(导致可能难以诊断错误)。这使人们质疑首先引入streamoff类型的整个理由。

这是故意的还是标准的缺陷?

1 个答案:

答案 0 :(得分:5)

我认为您从中得出的结论是C ++流与fseek之间的不匹配会导致运行时错误,这是不正确的。情况似乎是:

  1. long是64位的系统上,streamoff被定义为long,并且seekoff函数调用fseek

  2. long是32位但操作系统支持64位文件偏移量的系统上,streamoff被定义为long long,并且seekoff调用一个称为fseekofseeko64接受64位偏移。

以下是我的Linux系统上seekoff的定义的摘录:

#ifdef _GLIBCXX_USE_LFS
    if (!fseeko64(_M_file, __off, __whence))
      __ret = std::streampos(ftello64(_M_file));
#else
    if (!fseek(_M_file, __off, __whence))
      __ret = std::streampos(std::ftell(_M_file));
#endif

LFS代表Large File Support

结论:尽管标准提出了streamoff的定义,表面上与seekoff调用fseek的要求相矛盾,但库设计人员理解他们必须调用{{1}的变体}接受操作系统支持的所有偏移量。