当前位置: 首页 > news >正文

C语言:lseek函数-----改变文件偏移量

1.文件偏移

  • 通常调用read或write每读写一个文件,就会改变文件的读写位置。在linux中同样可以使用lseek函数来修改文件偏移量,即读写位置。
  • 标准C库的fseek函数和系统函数lseek比较类似,fseek函数也可以移动当前读写位置(或者叫偏移量),其实fseek就是对lseek系统函数封装后实现的,快速回忆一下之前学习的fseek函数的作用及常用参数。
lseek函数
  • 函数原型:
#include <sys/types.h>
#include <unistd.h>
off_t  lseek(int fd, off_t offset, int whence);
  • 参数说明:

  • fd : 文件描述符

  • offset : 文件偏移量(offset为负值表示往前偏移,正值则表示往后偏移)

  • whence : 偏移位置(SEEK_SET,SEEK_CUR,SEEK_END)
      1. SEEK_SET表示从文件开头位置往后移动offset个字节,且offset只能为正数,如果offset为负数是没有意义的。
      2. SEEK_CUR表示从当前文件的位置往前或往后移动offset个字节,如果offset为正数则表示往后移动,为负数则表示往前移动。
      3. SEEK=END表示从文件末尾的位置往前或往后移动offset个字节,如果offset为正数则表示往后移动为负数则表示往前移动。
      在这里插入图片描述


这里给一些lseek函数的一些例子,注释说明了文件偏移量到的具体位置:
  lseek(fd , 0 , SEEK_SET); //文件开始位置
  lseek(fd , 0 , SEEK_END); //文件末尾位置
  lseek(fd , 10 , SEEK_END); //从文件末尾往后移动10个字节
  lseek(fd , -10 , SEEK_END); //从文件末尾往前移动10个字节
  lseek(fd , 100 , SEEK_SET); //从文件开始往后移动100个字节

返回值说明:
  成功返回文件当前读写位置相对于文件开始位置的偏移量(字节数),如果文件读写的位置是在末尾的话,返回值就是文件头与文件尾之间的字节数,也就是文件大小。失败返回-1并设置errno
  
注意几点:
  1. 如果文件偏移量往回超出文件头位置,则返回-1,文件指针不变,还是处于原来的位置。
  2. lseek并不适用与所有的文件类型,也就是说在管道,FIFO,socket或终端不能使用lseek函数,一旦调用将会失败,并设置errno为EPIPE。

  • lseek示例程序:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>int main(void) 
{int fd, n;char buf[] = "hello world test \n";char ch;fd = open("test.txt", O_RDWR|O_CREAT, 0644);if(fd < 0){perror("open lseek.txt error");exit(1);}//使用fd对打开的文件进行写操作,写完后文件指针位置位于文件结尾处write(fd, buf, strlen(buf));   /*注意:读和写操作使用同一偏移位置,由于文件指针位于末尾,因此后面的read就会读不到数据了这一行的目的是把文件指针移动到文件头位置,这样下面的代码就能读到数据了*/lseek(fd , 0 , SEEK_SET);if(n == -1){perror("lseek fail");exit(1);}//lseek移到文件开头,read就能读取到数据了while((n = read(fd, &ch, 1))){if(n < 0){perror("read error");exit(1);}//将文件内容按字节读出,写到屏幕write(STDOUT_FILENO, &ch, n);  }close(fd);return 0;
}
  • 通过lseek计算文件大小
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>int main(void)
{int fd;char buf[] = "hello world"; fd = open("lseek.txt", O_RDWR | O_CREAT, 0664);if(fd < 0){perror("open lseek.txt error");exit(1);}write(fd , buf , strlen(buf));//lseek函数会从起始位置开始算到文件末尾,就能求出文件的长度了int len = lseek(fd, 0, SEEK_END);if(len == -1){perror("lseek error");exit(1);}//lseek函数的返回值就是文件的大小printf("file len = %d\n", len);close(fd);return 0;
}
  • 扩展文件大小

    lseek函数还可用于扩展文件大小,但是单独使用lseek是不能达到扩展文件的,还必须发生一次IO操作才能扩展文件大小。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>int main(void)
{int fd, n;char msg[] = "It's a test for lseek\n";char ch;fd = open("lseek.txt", O_RDWR|O_CREAT|O_TRUNC, 0644);if(fd < 0){perror("open lseek.txt error");exit(1);}//扩展文件大小100字节int ret = lseek(fd, 100, SEEK_SET);if (ret == -1) {perror("lseek error");exit(1);}//发生一次I/O操作write(fd, "\0", 1);  //位移到文件尾部int len = lseek(fd, 0, SEEK_END);printf("file size is %d\n", len);close(fd);return 0;
}
http://www.xdnf.cn/news/833977.html

相关文章:

  • 正则表达式(python)
  • WeakHashMap
  • 不会前端也可以看得懂的3种DIV+CSS布局技术
  • 常见功能测试点的测试用例大全(干货)
  • php文件777访问权限,奇怪的php文件读写权限问题【全777+apache:apache】?
  • C语言-static的用法
  • 网络安全人士必备的30个安全工具
  • RedHat 下载地址
  • 查看iOS中app的bundleId
  • 国标二阶段VIR消息集调试总结
  • 深度剖析单点登录流程原理,从0带你手写一个SSO
  • 【C语言】每日一代码:最大公约数
  • 共享开源地址
  • 学Python要是这几个网站都不知道,真的就白学了
  • 网络性能测试工具Iperf/Jperf解读
  • python批量下载csdn文章
  • OpenGLES系列demo之框架简介
  • C++中istringstream、ostringstream、stringstream 的用法
  • 《apue》 首次拜读完经典之作,两三记录
  • 【知识整理】MySQL数据库开发设计规范
  • parentNode和offsetParent的使用
  • simulink仿真技术简介
  • 延迟加载(Lazyload)三种实现方式
  • 2024年最全速看!成为黑k必看13个网站,简称网站大全!_红黑联盟官方网站,2024年最新看看这篇文章吧
  • log4cpp初入门
  • linux查看7799端口使用情况,OEM12C安装文档
  • 使用Flash_TooL软件刷机Android 手机步骤
  • ADODB 使用说明
  • Manifest文件详解
  • IF函数超实用的12种经典用法