目录
lseek函数介绍
一般情况下,read/write隐式改变文件指针,而lseek函数可以显式改变文件指针。
应用场景:若想要人为地随意更改文件指针,则需要lseek函数(文件指针不能直接调用,需要通过lseek)。
查看系统调用:man -2 lseek,查看详细内容如下::
具体调用为:off_t lseek(int fd,off_t offset,int whence)
其中
fd:需要操作的文件
offset:偏移量-->一般向后偏移
whence:参照物,有以下3种类型:
SEEK_SET:文件头
SEEK_CUR:当前文件指针位置
SEEK_END:文件尾
返回值为偏移后的文件指针位置(相对于文件内容开头)
注:
read和write函数都是从当前文件指针处开始操作的,所以当我们用lseek显式
将文件指针移动后,那么再进行read/write时就是从移动过后的位置开始的。
例如当前文件内容为:
示例代码:
#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main(int argc,char *argv[])
{
//打开文件
int fp = -1;
char buf[20]={0};
fp = open("1.txt",O_RDWR);
if (fp == -1){
perror("filed because");
return 0;
}else{
printf("open success!\n");
}
//移动文件指针
lseek(fp,3,SEEK_SET);
//读文件
int res = read(fp,buf,20);
if (res<0){
perror("filed because");
} else{
printf("The file has %dB\n",res);
printf("The content is [%s]\n",buf);
}
close(fp);
return 0;
}
编译运行后结果为:
我们发现进行read时,就是从移动过后的位置开始。
lseek计算文件长度
当文件指针指向文件开头时,调用lseek将文件指针移动到末尾,返回值即为文件指针距离文件开头的偏移量,即文件长度。
故int f_size = lseek(fd,0,SEEK_END)即可得出文件长度为f_size。
#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main(int argc,char *argv[])
{
int fd=-1;
if (argc!=2){
printf("pelase put in the file name.\n");
}
//打开文件
fd = open(argv[1],O_RDONLY);
if (fd==-1){
perror("open failed because");
_exit(-1);
}else {
printf("the file id is:%d\n",fd);
}
//求文件长度
int f_long=lseek(fd,0,SEEK_END);
if (f_long==-1){
perror("open failed because");
_exit(-1);
}else{
printf("the size of %s is %d\n",argv[1],f_long);
}
}
运行结果如下
我们可以发现结果与文件长度大小一致 。
lseek构建空洞文件
空洞文件应用场景:大多为多线程共享操作文件。创建大文件时,从头开始构建文件的时间会很长,所以我们将该文件分为多段,采用多线程,每个线程分配一段,对其负责的段进行写入。
空洞文件:
概念:空洞文件,即该文件中有一段为空。
普通文件中间是不能有空的,因为我们write时文件指针是依次从前到后移动,不可能绕过前部分直接到后部分。
创建空洞文件方法:打开文件后,用lseek跳过一段,在进行write,则会形成空洞文件。