Linux 系统编程 lseek函数

Linux 系统编程 lseek函数

lseek


官方描述

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

个人理解

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

偏移量

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

头文件

#include //包含在了unistd中
#include 

函数签名

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 
#include 
#include 
#include 

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 
#include 
#include 

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 
#include 
#include 
#include 

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

你可能感兴趣的:(Linux系统编程,linux)