31_lseek详解

seek查找,lseek前后移动

(1)文件指针:打开之后,文件内存存着呢,读写时是对内存操作,是操作静态文件,只有保存时存静态文件,动态文件在内存中就是文件流的形式。

(2)文件流很长,我们当前操作的是哪个位置,也就是光标位置给我们提供即将操作的位置信息,GUI界面下告诉人操作位置,

内存中没有光标,是用指针存放的,文件管理表(在进程管理表内)中的指针,文件管理表中的一个成员(光标),文件指针是vnode中的一个元素,这个指针表示当前正在操作文件流的哪个位置,这个指针不能被直接访问,Linux系统中,用lseek来访问光标位置,让文件指针(光标)动,文件指针默认在打开时指向文件开头,write和read本身自带移动文件指针的功能,所以读写n个字节后,文件指针会自动向后移动


参数,fd文件描述符,offset偏移量,whence,参考位置是文件头/当前位置/文件尾


返回值是相对文件开头的偏移字节数

#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>


int main(void)
{
	int fd = -1;//文件描述符
	char buf[100] = {0};
	char writebuf[20] = "i love linux LT.";
	int ret = 0;
	/*打开一个文件*/
	fd = open("a.txt",O_RDWR);
	if(-1 == fd)
	{
		printf("文件打开错误.\n");	
	}
	else
	{
		printf("文件打开成功.  fd = %d.\n",fd);
		
	}
	
	/*写文件*/
	#if 0
	ret = write(fd, writebuf, strlen(writebuf));
	if(ret < 0)
	{
		printf("写入失败.\n");
	}
	else
	{
		printf("写入的字节数为:%d.\n",ret);	
	}
	#endif
	
	ret = lseek(fd, 3, SEEK_SET);  //从开始移动4位,因为是从0开始计数的
	
	/*读取文件的内容*/
	#if 1 
	ret = read(fd, buf, 20);
	if(-1 == ret)
	{
		printf("读取失败.\n");
	}
	else
	{
		printf("读出的字节数为:%d.",ret);	
		printf("文件内容为:[%s].",buf);	
	}
	#endif
	
	
	/*关闭一个文件*///关闭一般都不会出什么错误,所以返回值也不去管它了 
	close(fd);
	
	return 0;

}

之前课程,我们写一个文件写入12个字节。想读出,但是读出的一片空白,原因是文件指针(光标)移动到文件末尾,导致什么东西也读不到。


用lseek计算文件的长度

Linux中并没有一个API能计算文件的长度,但是做项目时候,经常要知道文件得长度,此时可以用lseek来自己写一个函数,

#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;//文件描述符
	int ret = -1;
	
	if(argc != 2)
	{
		printf("usage: %s filename \n", argv[0]);//输入./a.out后面没跟文件名不行
		_exit(-1);
		
		
	}
	
	/*打开一个文件*/
	fd = open(argv[1], O_RDONLY);
	if(-1 == fd)
	{
		printf("文件打开错误.\n");	
	}
	else
	{
		printf("文件打开成功.  fd = %d.\n",fd);
		
	}
	
	//打开文件之后,指正指向文件开头
	//我们用lseek将文件指针移动到末尾,返回值就是文件的末尾的偏移量,就是文件的长度
	ret = lseek(fd, 0, SEEK_END);
	printf("文件长度是:%d./n", ret);
}

Linux下的代码是

root@ubuntu:/mnt/hgfs/05_winshare# gcc cal_len.c 
root@ubuntu:/mnt/hgfs/05_winshare# ./a.out a.txt 
文件打开成功.  fd = 3.
root@ubuntu:/mnt/hgfs/05_winshare# ls -l
total 82415
-rwxrwxrwx 1 root root      991 Mar 17 22:21 a.c
-rwxrwxrwx 1 root root     7442 Mar 17 22:43 a.out
-rwxrwxrwx 1 root root 84380262 Sep 13  2017 arm-2009q3.tar.bz2
-rwxrwxrwx 1 root root       19 Mar 17 22:05 a.txt   //此处显示改文件就是19个字节
-rwxrwxrwx 1 root root     1117 Mar 14 06:43 b.c
-rwxrwxrwx 1 root root     7610 Mar 14 06:44 b.out
-rwxrwxrwx 1 root root      753 Mar 17 22:43 cal_len.c
drwxrwxrwx 1 root root        0 Sep 26 06:05 s5pv210

这是为什么有的能显示中文,有的显示乱码。

lseek和空洞文件

空洞文件:文件中间有一段是空的

普通文件可以用lseek搞成空洞文件

我们打开一个文件,用lseek往后移动,就会弄成一个空洞文件

空洞文件平时不怎么用,这种技术是有用的,多线程操作文件是极其有用的,我们想能用更快的速度创建文件,如果从头开始一次构建,时间太长了,智能分段来完成,将文件分为多段,多线程操作一段的写入,用空洞文件的理论

文件是一个流,这个流是用文件指针指导的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值