lseek(2) - Linux 手册页
名称
lseek - 重定位读/写文件偏移量概要
#include <sys/types.h>#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
描述
- SEEK_SET
- 偏移量设置为 offset 字节。
- SEEK_CUR
- 偏移量设置为其当前位置加上 offset 字节。
- SEEK_END
- 偏移量设置为文件大小加上 offset 字节。
lseek() 函数允许将文件偏移量设置到文件末尾之外(但这不会改变文件的大小)。如果稍后在此点写入数据,则对 gap(“空洞”)中数据的后续读取将返回空字节 (aq\0aq),直到实际将数据写入 gap。
查找文件数据和空洞
从 3.1 版本开始,Linux 支持 whence 的以下附加值:- SEEK_DATA
- 将文件偏移量调整到文件中大于或等于 offset 的下一个包含数据的的位置。如果 offset 指向数据,则将文件偏移量设置为 offset。
- SEEK_HOLE
- 将文件偏移量调整到文件中大于或等于 offset 的下一个空洞。如果 offset 指向空洞的中间,则将文件偏移量设置为 offset。如果没有空洞在 offset 之后,则将文件偏移量调整到文件末尾(即,任何文件末尾都有一个隐式空洞)。
在上述两种情况下,如果 offset 指向文件末尾之外,lseek() 将失败。
这些操作允许应用程序映射稀疏分配文件中存在的空洞。这对于诸如文件备份工具之类的应用程序很有用,这些应用程序在创建备份时可以节省空间,并在具有发现空洞机制的情况下保留空洞。
就这些操作而言,空洞是未在底层文件存储中(通常)分配的零序列。但是,文件系统不一定报告空洞,因此这些操作不能保证是映射文件实际分配的存储空间的机制。(此外,实际写入底层存储的零序列可能不会报告为空洞。)在最简单的实现中,文件系统可以通过始终使 SEEK_HOLE 返回文件末尾的偏移量,并始终使 SEEK_DATA 返回 offset(即,即使 offset 指向的位置是空洞,也可以认为它由零序列的数据组成)来支持这些操作。
返回值
成功完成时,lseek() 返回从文件开头开始以字节为单位测量的结果偏移量位置。发生错误时,返回值为 (off_t) -1,并且 errno 设置为指示错误。错误
- EBADF
- fd 不是一个打开的文件描述符。
- EINVAL
- whence 无效。或者:结果文件偏移量将为负数,或者超出可寻址设备的末尾。
- EOVERFLOW
- 结果文件偏移量无法在 off_t 中表示。
- ESPIPE
- fd 与管道、套接字或 FIFO 关联。
- ENXIO
- whence 为 SEEK_DATA 或 SEEK_HOLE,并且当前文件偏移量超出文件末尾。
符合
SVr4, 4.3BSD, POSIX.1-2001。SEEK_DATA 和 SEEK_HOLE 是非标准扩展,也存在于 Solaris、FreeBSD 和 DragonFly BSD 中;它们被提议包含在下一个 POSIX 修订版(Issue 8)中。
说明
某些设备无法寻址,并且 POSIX 没有指定哪些设备必须支持 lseek()。在 Linux 上,在终端设备上使用 lseek() 会返回 ESPIPE。
在转换旧代码时,使用以下宏替换 whence 的值:
| old | 新建 |
| 0 | SEEK_SET |
| 1 | SEEK_CUR |
| 2 | SEEK_END |
| L_SET | SEEK_SET |
| L_INCR | SEEK_CUR |
| L_XTND | SEEK_END |
请注意,由 dup(2) 或 fork(2) 创建的文件描述符共享当前文件位置指针,因此对这些文件的寻址可能受到竞争条件的影响。