Linux系统IO函数lseek函数

Posted 傅耳耳

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux系统IO函数lseek函数相关的知识,希望对你有一定的参考价值。

Linux系统IO函数—lseek函数

1.1 lseek函数与标准C库的fseek函数

lseek函数对应标准C库中的fseek函数

查看标准C库中的fseek函数使用说明:

(shell输入)

man 3 fseek

fseek函数:

#include <stdio.h>
int fseek(FILE *stream, long offset, int whence);

查看Linux系统的lseek函数使用说明:

man 2 lseek

lseek函数:

#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);

<unistd.h>为UNIX系统的标准库

fseek和lseek差别:

  • 第一个参数:FILE *streamint fd
  • 第二个参数:long 类型和 off_t 类型

off_t 为一个宏定义,可以逐步找到源码查看其底层

  1. off_t<sys/types.h> 文件:
typedef __off_t off_t;
  1. __off_t<bits/types.h> 文件:
# define __STD_TYPE		typedef
__STD_TYPE __OFF_T_TYPE __off_t;/* Type of file sizes and offsets.*/
  1. __OFF_T_TYPE<typesizes.h> 文件:
#define __SLONGWORD_TYPE	long int
# define __SYSCALL_SLONG_TYPE	__SLONGWORD_TYPE
#define __OFF_T_TYPE		__SYSCALL_SLONG_TYPE

off_t 底层就是 long int 类型

1.2 lseek函数详解

#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);

lseek函数用来更改文件指针位置

  • 参数
    • fd:文件描述符,通过open得到,通过fd操作某个文件
    • offset:偏移量
    • whence
      • SEEK_SET:(从文件头开始偏移)设置文件指针的偏移量
      • SEEK_CUR:(从当前位置开始偏移)设置偏移量:当前位置 + 第二个offset的值
      • SEEK_END:设置偏移量:文件的大小(文件结尾) + 第二个参数offset的值
  • 返回值:返回文件指针的位置

1.3 lseek函数主要作用

1. 移动文件指针到文件头
lseek(fd, 0, SEEK_SET);
2. 获取当前文件指针的位置
lseek(fd, 0, SEEK_CUR);
3. 获取文件长度
lseek(fd, 0, SEEK_END);
4. 拓展文件的长度,当前文件10b, 110b, 增加100个字节
lseek(fd, 100, SEEK_END);

注意:要写入一个数据才有效

1.4 lseek函数实现文件拓展

编写lseek.c文件:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>

int main() 

    // 扩展文件长度,执行写操作
    int fd = open("hello.txt", O_RDWR);

    if(fd == -1) 
        perror("open");
        return -1;
    

    // 拓展文件的长度 增加100个字节
    int ret = lseek(fd, 100, SEEK_END);

    if(ret == -1) 
        perror("lseek");
        return -1;
    

    // 关闭文件
    close(fd);

    return 0;

shell编译并运行:

fuerer@fuerer-virtual-machine:~/Linux/lesson11$ gcc lseek.c -o lseek
fuerer@fuerer-virtual-machine:~/Linux/lesson11$ ./lseek
fuerer@fuerer-virtual-machine:~/Linux/lesson11$ ll
总用量 28
drwxrwxr-x  2 fuerer fuerer 4096 324 11:21 ./
drwxrwxr-x 12 fuerer fuerer 4096 324 11:02 ../
-rw-rw-r--  1 fuerer fuerer   12 324 11:16 hello.txt
-rwxrwxr-x  1 fuerer fuerer 8432 324 11:21 lseek*
-rw-rw-r--  1 fuerer fuerer 1580 324 11:21 lseek.c

hello.txt文件长度并没有拓展100个字节

原因】lseek仅仅移动指针,若想实现文件扩展,需要写入一个空数据

在执行lseek后加上写入空数据操作write(fd, " ", 1);

完整文件如下:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>

int main() 

    // 扩展文件长度,执行写操作
    int fd = open("hello.txt", O_RDWR);

    if(fd == -1) 
        perror("open");
        return -1;
    

    // 拓展文件的长度 增加100个字节
    int ret = lseek(fd, 100, SEEK_END);

    if(ret == -1) 
        perror("lseek");
        return -1;
    

    // lseek仅仅为移动指针
    // 若想真正实现拓展,要写入一个空数据
    write(fd, " ", 1);

    // 关闭文件
    close(fd);

    return 0;

再次编译运行:

fuerer@fuerer-virtual-machine:~/Linux/lesson11$ gcc lseek.c -o lseek
fuerer@fuerer-virtual-machine:~/Linux/lesson11$ ./lseek
fuerer@fuerer-virtual-machine:~/Linux/lesson11$ ll
总用量 28
drwxrwxr-x  2 fuerer fuerer 4096 324 11:26 ./
drwxrwxr-x 12 fuerer fuerer 4096 324 11:02 ../
-rw-rw-r--  1 fuerer fuerer  113 324 11:27 hello.txt
-rwxrwxr-x  1 fuerer fuerer 8472 324 11:26 lseek*
-rw-rw-r--  1 fuerer fuerer 1697 324 11:26 lseek.c

hello.txt大小由 12字节 ——> 113字节

(扩展100个字节后,又写入了" "一个字节)

文件拓展功能有何用途?

下载软件使用lseek为软件提前申请好可用空间

以上是关于Linux系统IO函数lseek函数的主要内容,如果未能解决你的问题,请参考以下文章

4.lseek函数及共享文件

linux系统编程之lseek帮助文档

《Linux从0到99》九 基础IO

《Linux从0到99》九 基础IO

《Linux从0到99》九 基础IO

lseek 与 ioctl