欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

lseek函数,lseek函数详细说明,函数原型和头文件,lseek函数的详细使用,补充命令(文件IO)【linux】(h)

程序员文章站 2022-05-24 11:03:31
...

lseek函数

我们在前面的博客中,简单的用过lseek函数,在这篇博客,我们就来详细的介绍一下,lseek函数的一些具体的情况。

先回顾下之前用过的例子:

我们之前使用的时候目的就是要把文件指针指向文件头才能进行文件数据的读取。使用的位置是在文件读取的时候:

lseek函数,lseek函数详细说明,函数原型和头文件,lseek函数的详细使用,补充命令(文件IO)【linux】(h)
lseek函数,lseek函数详细说明,函数原型和头文件,lseek函数的详细使用,补充命令(文件IO)【linux】(h)

lseek函数详细说明

函数原型和头文件

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

我们也可以通过帮助手册进行查看:
man lseek

lseek函数,lseek函数详细说明,函数原型和头文件,lseek函数的详细使用,补充命令(文件IO)【linux】(h)

功能
调整读写的位置,就像在纸上写字时,挪动笔尖所指位置是一样的。
C库的标准io函数里面有一个fseek函数,也是用于调整读写位置的,fseek就是对lseek系统函数封装后实现的,后面讲到标准io时,还会讲到fseek函数。

返回值
调用成功

返回当前读写位置相对于文件开始位置的偏移量(字节)。
可以使用lseek函数获取文件的大小,将文件读写的位置移动到最末尾,然后获取返回值,这个返回值就是文件头与文件尾之间的字节数,也就是文件大小。

调用失败
返回-1,并给errno设置错误号。

参数

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

1)fd:文件描述符,指向打开的文件

2)whence
粗定位,选项有:
SEEK_SET:调到文件起始位置
SEEK_CUR:调到文件当前读写的位置
SEEK_END:调到文件末尾位置
3)offset
精定位:微调位置
从whence指定的位置,向前或者向后移动指定字节数。
为负数:向前移动指定字节数
为正数:向后移动指定字节数

不过当whence被指定为SEEK_SET时,如果offset被指定为负数的话,是没有意义,因为已经到文件头上了,在向前移动就越界了,不再当前文件的范围内了,如果非要向前调整,lseek函数会报错。

lseek函数的详细使用

我们首先来演示通过将位置调整到文件末尾所返回的文件大小:
lseek函数,lseek函数详细说明,函数原型和头文件,lseek函数的详细使用,补充命令(文件IO)【linux】(h)
lseek函数,lseek函数详细说明,函数原型和头文件,lseek函数的详细使用,补充命令(文件IO)【linux】(h)

执行结果为:
lseek函数,lseek函数详细说明,函数原型和头文件,lseek函数的详细使用,补充命令(文件IO)【linux】(h)

我们可以看到打印出来大小为11,我们查看file.txt里面的内容,我们可以通过ls -l查看文件属性来查看文件大小:
lseek函数,lseek函数详细说明,函数原型和头文件,lseek函数的详细使用,补充命令(文件IO)【linux】(h)

我们再通过以下代码,把文件位置调整到文件末尾,然后再向前移动10个字节:

lseek函数,lseek函数详细说明,函数原型和头文件,lseek函数的详细使用,补充命令(文件IO)【linux】(h)
lseek函数,lseek函数详细说明,函数原型和头文件,lseek函数的详细使用,补充命令(文件IO)【linux】(h)

执行结果为:

lseek函数,lseek函数详细说明,函数原型和头文件,lseek函数的详细使用,补充命令(文件IO)【linux】(h)

总共11个字节 向前移动了10个到了第一个字节。从文件开头到文件位置只有一个字节所以size 为1 , 从1的位置看是向后读取 所以读取出来数据为ello world

补充命令

od -c 文件 : 以字符形式查看文件内容。
当你不知道文件内容有一些不可见的字符,或者不知道文件内容的具体情况的时候,我们就可以使用上面命令进行查看分析。

我们接下来看以下代码,我们这次把文件位置调整到文件头并且在细调整的时候把值设置为负数。

lseek函数,lseek函数详细说明,函数原型和头文件,lseek函数的详细使用,补充命令(文件IO)【linux】(h)
lseek函数,lseek函数详细说明,函数原型和头文件,lseek函数的详细使用,补充命令(文件IO)【linux】(h)
执行结果为:
lseek函数,lseek函数详细说明,函数原型和头文件,lseek函数的详细使用,补充命令(文件IO)【linux】(h)

错误为无效参数,已经到了文件头了,再向前移动就会出现越界。

我们再次进行修改代码 把参数改为:

lseek  (fd,10.SEEK_CUR);

执行结果为:
lseek函数,lseek函数详细说明,函数原型和头文件,lseek函数的详细使用,补充命令(文件IO)【linux】(h)

我们再次进行修改代码 把参数改为:

lseek  (fd,10.SEEK_SET);

执行结果为:
lseek函数,lseek函数详细说明,函数原型和头文件,lseek函数的详细使用,补充命令(文件IO)【linux】(h)
我们可以看到上面两个代码的执行结果是一样的。

出现这样结果的原因就是:
open这个的时候默认读写位置就是文件头,所以打开文件的时候设置SEEK_SET是没有意义的,设置SEEK_CUR的时候,打开文件之后的读写位置就是文件头,当设置为当前位置的时候,位置是没有移动的。

那么SEEK_CUR 我们更多的使用的使用是从当前位置向前或者向后移动。

接下来我们来看一下下面的情况:
我们设置两个,ret来调整文件位置:
代码演示:
lseek函数,lseek函数详细说明,函数原型和头文件,lseek函数的详细使用,补充命令(文件IO)【linux】(h)
lseek函数,lseek函数详细说明,函数原型和头文件,lseek函数的详细使用,补充命令(文件IO)【linux】(h)

执行结果为:
lseek函数,lseek函数详细说明,函数原型和头文件,lseek函数的详细使用,补充命令(文件IO)【linux】(h)

buf里面没有读取到任何数据,上面的实现就是从文件末尾向前移动10个位置,再从当前位置向后移动10个位置,又到了文件末尾,所以没有读取到任何数据。

小结

读者可以自行验证lseek的其他不同参数在文件中组合使用过程中文件位置移动的不同体现。

相关标签: Linux系统编程