lseek函数的三种用法以及open函数的补充

本文主要介绍了lseek函数的三个作用,包括调整文件读写位置、计算文件大小和拓展文件。详细说明了lseek函数的参数和返回值,还提及write函数参数、open函数的阻塞与非阻塞设置,以及fcntl函数用法,最后补充了文件重命名的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

lseek的有三个作用:

  • 1.调整文件读写位置
  • 2.计算文件大小,因为返回值是文件开头到目前读写位置的长度可以用这个属性进行查看大小
  • 3.作为一个文件拓展

首先了解一下lseek函数

lseek:移动文件读写位置

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

  • fd文件描述符

  • offset 偏移量一般设置为0,一般在拓展文件的时候需要设置大小,下面举例子

  • whence,当前读写位置,一般包含三种:

  • SEEK_SET:文件开始位置

  • SEEK_CUR:文件当前位置

  • SEEK_END:文件末尾

  • 返回值:成功返回当前位置到开始的长度,失败则返回-1并且设置error

调整文件读写位置:需求打开文件输入内容,读取内容并把内容输出到终端
在这里插入图片描述
这里我写一下为啥write函数第一个参数写标准输出流形式,其实写1也可以,对应文件操作符表,只是代码中直接出现魔幻数字不好
2.计算文件大小,因为返回值是文件开头到目前读写位置的长度可以用这个属性进行查看大小

在这里插入图片描述
3.作为一个文件拓展
在这里插入图片描述
看一下效果:
在这里插入图片描述
这里xxx文件大小为1025是因为我们写入了一个a

这里加一点,open函数一般以阻塞打开,如果要变成非阻塞就要添加open第二个参数的第三个可选项O_NONBLOCK。函数形式为open(文件名,必选项|O_NONBLOCK)详情见open函数手册,设置open函数为非阻塞还有一种办法就是设置fcntl函数,那就不需要在open函数中再添加第三个可选项了,只需加入如下代码,fcntl函数用法比较复杂,具体参考手册
在这里插入图片描述
插入一个忘了的知识点:
没有专门的重命名 命令用 mv a b 就可以重命名了=========================================mv :move 移动文件(延伸功能:重命名,linux系统没有专门的重命名命令) 基本格式: 移动文件:mv 文件名 移动目的地文件名 重命名文件:mv 文件名 修改后的文件名

<think>好的,我现在需要回答用户关于Linux系统中lseek函数的参数和返回值的问题。用户已经提供了几个站内引用,我需要仔细阅读这些引用内容,提取关键信息,并结合自己的知识来组织回答。首先,用户提供的引用[1]提到lseek函数的返回值类型是off_t,并且有一个示例函数oldpos,参数包括文件描述符fd、偏移量dist和基准位置base。引用[2]详细说明了lseek的三个参数,特别是第二个参数offset和第三个参数whence的关系,比如设置为SEEK_END时可以在文件末尾扩展文件大小。引用[3]特别指出lseek成功时返回新的文件偏移量,失败返回(off_t)-1,并且强调不能仅用小于0判断失败,因为偏移量可能为负,正确做法是检查是否等于-1并查看errno。引用[4]和[5]提到了stat函数和creat函数,可能与lseek的使用场景相关,但用户的问题集中在lseek的参数和返回值,所以暂时可能不需要深入这些内容。 接下来,我需要整理lseek函数的参数和返回值:参数:1.文件描述符fd:必须是已打开的有效文件描述符。2.偏移量offset:根据whence参数进行移动的字节数,可以是正数、负数或零。3.基准位置whence:决定offset的参考点,通常有SEEK_SET(文件开头)、SEEK_CUR(当前位置)、SEEK_END(文件末尾)等选项。 返回值: -成功时返回新的文件偏移量(相对于文件开头的字节数),类型为off_t。 -失败时返回(off_t)-1,并设置errno来指示错误类型。需要注意用户引用[3]提到的错误判断方法,不能直接用返回值是否小于0,因为某些情况下偏移量可能合法为负数,比如在某些设备文件中。正确的做法是检查返回值是否为(off_t)-1,再结合errno判断错误。此外,用户引用[2]中的示例代码展示了如何用lseek扩展文件大小,通过将whence设为SEEK_END并设置offset为10,这样文件末尾后移了10字节,可能用于预分配空间。不过代码中缺少write操作,实际可能需要写入数据才能真正扩展文件,但用户的问题不在此,所以可能不需要详细展开。在回答结构上,应该按照用户的要求,分参数说明和返回值分析,并给出示例代码。同时,要引用相关的站内引用,如引用[3]关于返回值的注意事项,引用[2]关于参数使用示例。最后,生成相关问题需要考虑用户可能对lseek的扩展文件应用、错误处理、与其他函数(如stat)的关系等方面感兴趣。例如,如何用lseek调整文件大小,lseek和fseek的区别,或者lseek在文件空洞中的应用等。</think>### `lseek`函数参数与返回值详解 #### 一、参数说明 1. **文件描述符 (`int fd`)** - 必须是通过`open()`、`creat()`等系统调用获取的**有效描述符**[^5]。 - 若传入无效描述符,函数返回`-1`并设置`errno`为`EBADF`[^3]。 2. **偏移量 (`off_t offset`)** - 定义相对于基准位置(`whence`)的移动字节数,可为正数、负数或零。 - 示例: ```c lseek(fd, 10, SEEK_CUR); // 从当前位置向后移动10字节 lseek(fd, -5, SEEK_END); // 从文件末尾向前移动5字节 ``` 3. **基准位置 (`int whence`)** - 指定偏移量的参考点,支持以下常量: - **`SEEK_SET`**:文件开头(偏移量为正)[^2]。 - **`SEEK_CUR`**:当前文件位置(偏移量可正可负)[^3]。 - **`SEEK_END`**:文件末尾(偏移量可正可负,常用于扩展文件)[^2]。 - 示例: ```c lseek(fd, 0, SEEK_END); // 将偏移量设为文件末尾(常用于获取文件大小) ``` #### 二、返回值分析 - **成功时** 返回新的文件偏移量(类型为`off_t`),表示相对于**文件开头**的字节数。例如: ```c off_t new_offset = lseek(fd, 10, SEEK_SET); // new_offset = 10 ``` - **失败时** 返回`(off_t)-1`,并设置`errno`标识错误类型。需注意: - **不可仅用负值判断失败**:某些特殊文件(如设备文件)可能允许负偏移量[^3]。 - **正确错误检查方法**: ```c off_t result = lseek(fd, offset, whence); if (result == (off_t)-1) { perror("lseek failed"); // 常见错误:EBADF(无效描述符)、EINVAL(无效whence) } ``` #### 三、关键行为说明 1. **扩展文件大小** 通过将`whence`设为`SEEK_END`并指定正偏移量,可实现文件扩展: ```c lseek(fd, 100, SEEK_END); // 在文件末尾后扩展100字节(需配合写入操作) ``` > 注意:仅调用`lseek`不会实际分配磁盘空间,需后续执行`write()`写入数据[^2]。 2. **获取当前偏移量** ```c off_t pos = lseek(fd, 0, SEEK_CUR); // pos为当前偏移量 ``` 3. **处理特殊文件** - 某些设备文件(如`/dev/null`)可能不支持`lseek`,调用会返回`ESPIPE`错误[^3]。 #### 四、示例代码 ```c #include <unistd.h> #include <fcntl.h> int main() { int fd = open("test.txt", O_RDWR); if (fd == -1) { perror("open failed"); return 1; } // 将文件扩展为100字节(从末尾偏移90字节) off_t new_offset = lseek(fd, 90, SEEK_END); if (new_offset == (off_t)-1) { perror("lseek failed"); close(fd); return 1; } // 写入1字节以实际分配空间 write(fd, "A", 1); close(fd); return 0; } ``` #### 五、注意事项 1. **与`stat`的对比** `stat`函数通过结构体`struct stat`的`st_size`字段获取文件大小,而`lseek(SEEK_END)`返回的是逻辑大小(可能包含文件空洞)[^4]。 2. **文件空洞** 若通过`lseek`跳过部分偏移量后写入数据,中间未写入的区域会形成**文件空洞**,占用磁盘空间为0。 3. **线程安全** `lseek`修改的是内核中文件描述符的偏移量,多线程操作同一描述符时需加锁。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值