Linux系统编程|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同时操作同一文件时) 【Linux系统编程|Linux 系统编程 lseek函数】从距离文件头部 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

    推荐阅读