若一个矩形代表一个文件,这个矩形由七个小矩形组成,这七个小矩形(从左到右)分别代表该文件的第1,2,3,4,5,6,7个字节。当我们打开文件时,会有一个指针指向这个文件的第一个字节;使用read函数进行读操作,假如读了两个字节,指针就会向后移动两个字节,从“1”的位置移至“3”;当再次执行读操作时此时会从第一个字节开始读还是接着从“3”的位置开始读呢?答案是从指针指向的位置“3”开始读。同样地,写操作碰到这种这种情况也是如此。
如果想要移动指针,需要如何移动呢?需要使用lseek函数移动。
#include
#include
off_t lseek(int fd,off_t offset,int whence);
参数:
fd指的是文件描述符(从open系统调用返回来的)
whence:当前位置的基点,可以使用以下三组值:
1)SEEK_SET:相对于文件开头
2)SEEK_CUR:相对于当前的问价读写指针位置
3)SEEK_END:相对于文件末尾
offset:偏移量,单位是字节的数量,可以正可以负,如果是负值,表示向前移动;如果是正值,表示向后移动。
返回值:成功返回当前位移;失败返回-1.
1)把文件位置指针设置为100
lseek(fd,100,SEEK_SET)
指的是相对于文件的开头,把文件位置指针设置为100.就好比在读书的时候,从第一页往后数100页。
2)把文件位置设置为文件末尾
lseek(fd,0,SEEK_END)
指的是相对于文件的末尾,移动了0个字节。这就好比读书的时候,翻至最后一页,往前翻了0页,此时仍然在最后一页。也可以通过这种情况来计算文件的大小,因为它的返回值为当前位移。
3)确定当前的文件位置
lseek(fd,0,SEEK_CUR)
相当于文件当前读写指针的位置,移动了0个字节。好比在读书的时候,读到了第100页,没向前翻,也没有向后翻,这个“100页”就是当前的位置。
(1)对同一个文件读取两次
在使用read函数(read.c)的时候(嵌入式学习之linux系统编程—4 文件IO之read函数,之前为了验证读至文件末尾的时候,会返回0值,现在想在第一次读完文件的时候,进行第二次读写,而不是读完一次的时候读第二次会显示读至末尾,返回0值,应该如何设置呢?
这个时候就可以使用lseek函数,将指针从文件的末尾移动到文件的开头就可以啦!在第一次读与第二次读的操作之间加一条语句:
lseek(fd,0,SEEK_SET)
这样就可以将指针挪到开头啦。
c代码如下:
#include
#include
#include
#include
#include
#include
int main(int argc,char *argv[])
{
int fd;
char buf[32]={0};
ssize_t ret;
fd = open("a.c",O_RDWR);
if(fd<0){
printf("open is error\n");
return -1;
}
printf("fd is %d\n",fd);
ret=read(fd,buf,32);
if (ret<0){
printf("read is error\n");
return -2;
}
printf("buf is %s\n",buf);
printf("ret is %ld\n",ret);
lseek(fd,0,SEEK_SET);
ret=read(fd,buf,32);
printf("ret is %ld\n",ret);
close(fd);
return 0;
}
在ubuntu界面的a.c文件中键入“helloworld!”,执行gcc编译,并执行可执行文件,可得到结果如下:
(2)测试SEEK_CUR参数
#include
#include
#include
#include
#include
#include
int main(int argc,char *argv[])
{
int fd;
char buf[32]={0};
ssize_t ret;
fd = open("a.c",O_RDWR);
if(fd<0){
printf("open is error\n");
return -1;
}
printf("fd is %d\n",fd);
ret=read(fd,buf,5);
//设置只读取五个字节
if (ret<0){
printf("read is error\n");
return -2;
}
printf("buf is %s\n",buf);
printf("ret is %ld\n",ret);
ret=lseek(fd,0,SEEK_CUR);
//ret=read(fd,buf,32);
printf("ret is %ld\n",ret);
close(fd);
return 0;
}
重新在ubuntu界面编译生成新的可执行文件SEEK_CUR,运行结果如下:
(3)测试SEEK_END参数(计算文件的长度)
直接将指针移动到文件的末尾
只需要将测试SEEK_CUR的C语言代码中的“ret=lseek(fd,0,SEEK_CUR);”改为“ret=lseek(fd,0,SEEK_END);”,在ubuntu界面编译并执行,结果如下图所示。