Linux 系统编程 lseek函数

Linux 系统编程 lseek函数

lseek


官方描述

重新设置读写文件的偏移量(reposition read/write file offset);

个人理解

设置光标的位置,从哪个位置开始读取或写入数据;

偏移量

每个打开的文件都记录着当前读写位置,打开文件时读写位置是0,表示文件开头,通常读写多少个字节就会将读写位置往后移多少个字节。但是有一个例外,如果以O_APPEND方式打开,每次写操作都会在文件末尾追加数据,然后将读写位置移到新的文件末尾。lseek和标准I/O库的fseek函数类似,可以移动当前读写位置(或者叫偏移量)。

头文件
#include <sys/types.h>//包含在了unistd中
#include <unistd.h>
函数签名
off_t lseek(int fd, off_t offset, int whence);
参数

fd:
文件描述符;
offset:
偏移量,相对于 whence,自然数;
whence:
int类型,一般传以下宏;
SEEK_SET;文件头部
SEEK_CUR;当前位置
SEEK_END; 文件尾部

返回值

Upon successful completion, lseek() returns the resulting offset location as measured in bytes from the beginning of the file.
一旦成功,返回当前位置到文件开始的字节总数;
On error, the value (off_t) -1 is returned and errno is set to indicate the error.
发生错误,返回-1,并设置errno;

lseek应用


更改文件偏移位(read/write同时操作同一文件时)

从距离文件头部 11个字节开始读取 10个字节的数据,再从 21(10+10+1)位置开始写入数据;

#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>

int main(){
	const char *pathname = "./test.txt";
	char buf[1024];
	int count = 10;
	int fd = open(pathname, O_RDWR | O_CREAT, 0664);
	// 偏移到距离头部第10个字节的位置,从后一个字节开始读取
	lseek(fd, 10, SEEK_SET);
	int rsize = read(fd, buf, count);
	printf("%s\n", buf);
	// 偏移到距离当前位置第10个字节的位置,从后一个字节开始写入
	lseek(fd, 10, SEEK_CUR);
	const char w_buf[] = "I like you guys!\n";
	count = sizeof(w_buf);
	int wsize = write(fd, w_buf, count);
	close(fd);
	return 0;
}

  1. 偏移到 10位置,从11位置开始读取数据;
计算文件大小

偏移到文件末尾,返回字节总数,即为文件大小;

#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>

int main(){
	const char *pathname = "./test.txt";
	int fd = open(pathname, O_RDWR | O_CREAT, 0664);
	// 偏移到文件尾部的位置,返回总节数
	int file_size = lseek(fd, 0, SEEK_END);
	printf("%d\n", file_size);
	close(fd);
	return 0;
}
拓展文件

使用lseek拓展文件:write操作才能实质性的拓展文件(引起IO操作)。单lseek是不能进行拓展的;

#include <unistd.h>
#include <stdio.h>
#include <error.h>
#include <fcntl.h>

int main(){
	const char *pathname = "./test.txt";
	int fd = open(pathname, O_RDWR | O_CREAT, 0664);
	// 偏移到文件尾部的位置,返回总节数
	int file_size = lseek(fd, 6, SEEK_END);
	printf("%d\n", file_size);
	write(fd, "a", 1);//  总字节数 = 原字节总数+6+1
	close(fd);
	return 0;
}

注:

  1. wq保存文件时,会检查末尾有无 [ \n ],没有的话会加上然后保存退出;
  2. q不会,对文件 write操作也不会;
  3. lseek 拓展的位置都是文件空洞 [ \0 ],可以使用 od指令查看;
od -tcx filename  查看文件的 16 进制表示形式      
od -tcd filename  查看文件的 10 进制表示形式  

注:

  1. x表示16进制,d表示 10进制;

fseek


fseek函数签名
int fseek(FILE *stream, long offset, int whence); 
fseek参数

stream:
FILE*(文件指针),表示要操作的文件(类似文件操作符的功能),句柄的句柄;
offset:
偏移量,相对于 whence,自然数;
whence:
int类型,一般传以下宏;
SEEK_SET;文件头部
SEEK_CUR;当前位置
SEEK_END; 文件尾部

fseek返回值

Upon successful completion, fgetpos(), fseek(), fsetpos() return 0, and ftell() returns the current offset. Otherwise, -1 is returned and errno is set to indicate the error.
成功返回0;失败返回-1,并设置errno;
特别的:超出文件末尾位置返回0;往回超出文件头位置,返回-1;

2020/07/23 17:30
@luxurylu

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值