Linux下每个打开的文件,都关联着一个“文件偏移量”,表示距离文件开始处偏移的字节数,通常是非负整数。
读、写文件都从该偏移量开始,偏移量随读、写的字节数增加。
默认情况,除非用O_APPEND 打开,初始文件偏移量为0.
函数接口:
#include<unistd.h>
off_t lseek(int fd, off_t offset, int whence);
参数:
- fd:打开的文件描述符
- offset,与whence相关:
- whence 为 SEEK_SET,则将偏移量设置为距离文件开始处offset 字节位置
- whence 为SEEK_CUR,则将偏移量设置为当前位置加offset字节处,offset 可正可负
- whence 为SEEK_END,则将偏移量设置为文件长度加offset字节处,offset 可正可负
返回值:成功返回新的偏移量,失败返回-1.
测试代码:
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
int main()
{
printf("seek set:%d cur:%d end:%d\n", SEEK_SET, SEEK_CUR, SEEK_END);
int fd = open("seektest.txt", O_RDWR | O_CREAT, 0600);
off_t pos = lseek(fd, 0, SEEK_CUR);
if (pos == -1)
printf("seek error\n");
else
printf("file offset:%zu\n", pos);
pos = lseek(fd, 10, SEEK_CUR);
if (pos == -1)
printf("seek file error\n");
else
printf("file offset:%zu\n", pos);
// 文件空洞
char* buf = "hello world.";
if (write(fd, buf, strlen(buf)) < 0)
{
printf("write file error\n");
return -1;
}
// 查看文件
// 管道 seek pipe
int pipefd[2];
if (pipe(pipefd) == -1)
{
printf("pipe error\n");
return -1;
}
pos = lseek(pipefd[0], 0, SEEK_CUR);
if (pos == -1)
{
printf("seek pipe error\n");
}
close(pipefd[0]);
close(pipefd[1]);
// 命名管道 seek fifo
int ret = mkfifo("myfifo", 0600);
fd = open("myfifo", O_RDWR);
if (fd < 0)
{
printf("open fifo error\n");
return -1;
}
pos = lseek(fd, 0, SEEK_CUR);
if (pos == -1)
printf("seek fifo error\n");
else
printf("fifo offset:%zu\n", pos);
}
运行,输出:
seek set:0 cur:1 end:2
file offset:0
file offset:10
seek pipe error
seek fifo error
查看文件空洞:
od -c seektest.txt
0000000 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 h e l l o
0000020 w o r l d .
0000026
左侧数字是八进制字节偏移量。
参考:
《Unix环境高级编程》3.6 小节