C++使用streamoff
类型来表示(文件)流中的偏移量,定义如下 [stream.types]:
using streamoff = implementation-defined ;
类型streamoff是有符号基本整数类型之一的同义词,大小足以表示操作系统的最大可能文件大小。287)
287) 通常为long long。
这样做有意义,因为它允许在大型文件内进行寻址(而不是使用可能仅32位宽度的long
)。
[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() == false
或者off != 0 && width <= 0
,则定位操作失败。否则,如果way != basic_ios::cur
或者off != 0
,并且(which & ios_base::out) == ios_base::out
,则调用fseek
来更改位置。
width>0
,则调用fseek(file,width * off,whence)
,否则调用fseek(file,0,whence)
。
fseek
接受一个long
参数。如果off_type
和streamoff
被定义为long long
(如标准建议的那样),则在调用fseek(file,width * off,whence)
时可能会发生向下转换为long
的情况(导致潜在难以诊断的错误)。这就对首次引入streamoff
类型的整个基本原理提出了质疑。这是有意还是标准中的缺陷?
seekoff
并不一定在底层使用fseek
。相反,fseek
的(可能是熟悉的?)行为被用来解释seekoff
在做什么。 - jjramseyfseek
相同的效果,就不必实际调用fseek
。但是,如果使用小于LONG_MIN
或大于LONG_MAX
的偏移量调用fseek
将没有任何效果,因此对于streamoff
比long
更宽的实现来说,该解释至少是不完整的。 - Keith Thompson