lseek(2) - Linux 手册页

名称

lseek - 重定位读/写文件偏移量

概要

#include <sys/types.h>
#include <unistd.h>

off_t lseek(int fd, off_t offset, int whence);

描述

lseek() 函数根据 whence 指令将与文件描述符 fd 关联的打开文件的偏移量重定位到参数 offset,具体如下:
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
whenceSEEK_DATASEEK_HOLE,并且当前文件偏移量超出文件末尾。

符合

SVr4, 4.3BSD, POSIX.1-2001。

SEEK_DATASEEK_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_SETSEEK_SET
L_INCRSEEK_CUR
L_XTNDSEEK_END

请注意,由 dup(2)fork(2) 创建的文件描述符共享当前文件位置指针,因此对这些文件的寻址可能受到竞争条件的影响。

参见

dup(2), fork(2), open(2), fseek(3), lseek64(3), posix_fallocate(3)

引用自

_llseek(2), afio(1), cpuid(4), dnet(3), dup2(2), explain(1), explain(3), explain_lseek(3), explain_lseek_or_die(3), explain_open_or_die(3), fsgrab(1), getdirentries(3), ksh93(1), lam_rfposix(2), myrescue(1), ncl_cgm(3), open_append(3), perl5004delta(1), perlfunc(1), pipe(7), pread(2), proc(5), qio(3), read(2), readahead(2), rmt(8), seekdir(3), spufs(2), spufs(7), star(1), stdin(3), tiffopen(3), vche(1), write(2), writev(2), x11vnc(1), xs(1), xxd(1), zshexpn(1)