For the complete documentation index, see llms.txt. This page is also available as Markdown.

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 相关联。

参见

dup(2), open(2), pathconf(2)

标准

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 的使用在英语语法上是不正确的,但出于历史原因予以保留。

最后更新于

这有帮助吗?