lseek(2)
lseek — 重新定位读/写文件偏移量
名称
lseek
库
Lb libc
概要
#include <unistd.h>
off_t
lseek(int fildes, off_t offset, int whence);描述
lseek() 系统调用根据 whence 指令将文件描述符 fildes 的偏移量重新定位到参数 offset。参数 fildes 必须是已打开的文件描述符。lseek() 系统调用按以下方式重新定位与文件描述符 fildes 关联的文件位置指针:
如果
whence为SEEK_SET,偏移量设置为offset字节。如果
whence为SEEK_CUR,偏移量设置为其当前位置加上offset字节。如果
whence为SEEK_END,偏移量设置为文件大小加上offset字节。如果
whence为SEEK_HOLE,偏移量设置为大于或等于所提供offset的下一个空洞的起始位置。空洞的定义见下文。如果
whence为SEEK_DATA,偏移量设置为大于或等于所提供offset的下一个非空洞文件区域的起始位置。
lseek() 系统调用允许将文件偏移量设置到超出文件现有末尾的位置。如果随后在此位置写入数据,则对间隙中数据的后续读取将返回零字节(直到实际有数据写入间隙)。然而,lseek() 系统调用本身不会扩展文件大小。
“hole”(空洞)定义为文件中连续的零值字节范围,但文件中的所有零值不保证都会被表示为 SEEK_HOLE 返回的空洞。文件系统可以选择用 SEEK_HOLE 暴露零值范围,但不强制要求。应用程序可以使用 SEEK_HOLE 来优化对零值范围的处理行为,但不能依赖它来找到文件中所有这样的范围。每个文件在文件末尾都被视为具有一个零大小的虚拟空洞。每个数据区域末尾存在空洞使得编程更加简单,同时也与 Solaris 中的原始实现保持兼容。这还使得当前文件大小(即文件末尾偏移量)会被返回,以表示在提供的 offset 之后没有更多空洞。应用程序应使用 fpathconf(_PC_MIN_HOLE_SIZE) 或 pathconf(_PC_MIN_HOLE_SIZE) 来确定文件系统是否支持 SEEK_HOLE。参见 pathconf(2)。
对于不提供空洞信息的文件系统,文件将被表示为一个完整的数据区域。
返回值
成功完成后,lseek() 返回从文件开头计算的偏移量位置(以字节为单位)。否则,返回值 -1,并设置 errno 以指示错误。
错误
lseek() 系统调用在以下情况下会失败,且文件位置指针保持不变:
[EBADF] fildes 参数不是已打开的文件描述符。
[EINVAL] whence 参数不是有效值,或者对于非字符特殊文件,结果文件偏移量为负值。
[ENXIO] 对于 SEEK_DATA,在提供的偏移量之后没有更多数据区域。由于文件末尾存在空洞,对于 SEEK_HOLE,仅当 offset 已经指向文件末尾位置时才返回此错误。
[EOVERFLOW] 结果文件偏移量无法在 off_t 类型的对象中正确表示。
[ESPIPE] fildes 参数与管道、socket 或 FIFO 相关联。
参见
标准
lseek() 系统调用预期遵循 IEEE Std 1003.1-2008 ("POSIX.1")。
SEEK_HOLE 和 SEEK_DATA 指令以及 ENXIO 错误预期遵循 IEEE Std 1003.1-2024 ("POSIX.1")。
历史
lseek() 函数出现于 Version 7 AT&T UNIX。
缺陷
如果 lseek() 系统调用在无法寻址的设备上操作,它仍会请求寻址操作并成功返回,即使没有执行任何寻址。由于 offset 参数会无条件地存储在该设备的文件描述符中,因此无法确认寻址操作是否成功(例如使用 ftell() 函数)。已知无法寻址的设备类型包括磁带机。
lseek() 系统调用不会检测可更换介质设备(如 DVD 或蓝光设备)中是否存在介质。因此,当没有介质存在时,请求的寻址操作仍会成功返回。
本文档对 whence 的使用在英语语法上是不正确的,但出于历史原因予以保留。
最后更新于
这有帮助吗?