【Linux系统编程】lseek函数

【Linux系统编程】lseek函数lseek

大家好,欢迎来到IT知识分享网。

 lseek函数

        所有打开的文件都有一个当前文件偏移量(current file offset),也叫读写偏移量和指针。文件偏移量通常是一个非负整数,用于表明文件开始处到文件当前位置的字节数(下一个read()或 write()操作的文件起始位置)。文件的第一个字节的偏移量为0。 ​ 文件打开时,会将文件偏移量设置为指向文件开始(使用O_APPEND除外),以后每次read()和write()会自动对其调整,以指向已读或已写数据的下一字节。因此连续的read()和write()将按顺序递进,对文件进行操作。

使用lseek函数可以改变文件的偏移量。

函数描述: ​ 移动文件指针

头文件: ​

 #include <sys/types.h>   #include <unistd.h>

函数原型:

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

函数参数:

fd:文件描述符

●offset:字节数,以whence参数为基点解释offset(偏移量)

●whence:解释offset参数的基点

SEEK_SET:文件偏移量设置为offset(开头) ​

SEEK_CUR:文件偏移量设置为当前文件偏移量加上offset,offset可以为 负数(末尾) ​

SEEK_END:文件偏移量设置为文件长度加上 offset,offset可以为负数

函数返回值:

●若lseek成功执行,则返回新的偏移量。

●失败返回-1并设置errno

lseek函数常用操作:

●文件指针移动到头部 ​ lseek(fd, 0,SEEK_SET);

●获取文件指针当前位置 ​ int len = lseek(fd,0,SEEK_CUR);

●获取文件长度 ​ int len = lseek(fd,0,SEEK_END);

lseek 实现文件拓展 ​

lseek(fd, n, SEEK_END);//扩展n个字节write();//扩展后需要执行一次写操作才能扩展成功

#include<stdio.h> #include<string.h> #include<unistd.h> #include<pthread.h> #include<fcntl.h> int main(int argc, char* argv[]) { int fd = open("./a.txt", O_RDWR); char buf[1024]; int read_count = read(fd, buf, 1); buf[read_count] = '\0'; printf("read_count = %d\n", read_count); printf("buf = %s", buf); int off = lseek(fd, 0, SEEK_SET); printf("off = %d\n", off); int write_count = write(fd, buf, read_count); printf("write_count = %d\n", write_count); close(fd); return 0; }

【Linux系统编程】lseek函数

确认是覆盖:

【Linux系统编程】lseek函数

#include<stdio.h> #include<string.h> #include<unistd.h> #include<pthread.h> #include<fcntl.h> int main(int argc, char* argv[]) { int fd = open("./a.txt", O_RDWR); char buf[1024]; int read_count = read(fd, buf, sizeof(buf)); buf[read_count] = '\0'; printf("read_count = %d\n", read_count); printf("buf = %s\n", buf); int off = lseek(fd, 0, SEEK_CUR);//当前文件偏移量 //int off = lseek(fd, 0, SEEK_END);//追加 printf("off = %d\n", off); int write_count = write(fd, buf, read_count); printf("write_count = %d\n", write_count); close(fd); return 0; }

【Linux系统编程】lseek函数

#include<stdio.h> #include<string.h> #include<unistd.h> #include<pthread.h> #include<fcntl.h> int main(int argc, char* argv[]) { int fd = open("./c.txt", O_RDWR); char buf[1024]; int read_count = read(fd, buf, sizeof(buf)); buf[read_count] = '\0'; printf("read_count = %d\n", read_count); printf("buf = %s\n", buf); int off = lseek(fd, 100, SEEK_END); printf("off = %d\n", off); close(fd); return 0; }

【Linux系统编程】lseek函数

a.txt大小没变,因为虽然扩容100,但是没用上。

#include<stdio.h> #include<string.h> #include<unistd.h> #include<pthread.h> #include<fcntl.h> int main(int argc, char* argv[]) { int fd = open("./c.txt", O_RDWR); char buf[1024]; int read_count = read(fd, buf, sizeof(buf)); buf[read_count] = '\0'; printf("read_count = %d\n", read_count); printf("buf = %s\n", buf); int off = lseek(fd, 100, SEEK_END); printf("off = %d\n", off); write(fd, " ", 1);//多加一字节 close(fd); return 0; }

【Linux系统编程】lseek函数

【Linux系统编程】lseek函数

练习:实现mycp指令

实现自己的cp指令mycp:

主函数传参: argc是参数个数,argv接收参数,第一个参数是函数名

#include<stdio.h> #include<string.h> #include<unistd.h> #include<pthread.h> #include<fcntl.h> #include<stdlib.h> int main(int argc, char* argv[]) { if(argc != 3) { printf("参数个数错误\n"); return -1; } int source_fd = open(argv[1], O_RDONLY);//路径 //有可能不存在,所以传O_CREAT; 还有可能比源文件大,所以传O_TRUNC int target_fd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644); //读源文件 char buf[1024]; int read_count = read(source_fd, buf, sizeof(buf)); printf("read_count = %d\n", read_count); //把buf写到target_fd里 int write_count = write(target_fd, buf, read_count); printf("write_count = %d\n", write_count); //关闭 close(source_fd); close(target_fd); return 0; }

原本b.txt里什么也没有

【Linux系统编程】lseek函数

原本b.txt内容比c.txt少,执行之后会覆盖,并且c.txt也变少了。

【Linux系统编程】lseek函数

目标文件不存在

【Linux系统编程】lseek函数

但是万一会有超过buf大小的,可以写一个循环

【Linux系统编程】lseek函数

【Linux系统编程】lseek函数

#include<stdio.h> #include<string.h> #include<unistd.h> #include<pthread.h> #include<fcntl.h> #include<stdlib.h> int main(int argc, char* argv[]) { if(argc != 3) { printf("参数个数错误\n"); return -1; } int source_fd = open(argv[1], O_RDONLY);//路径 //有可能不存在,所以传O_CREAT; 还有可能比源文件大,所以传O_TRUNC int target_fd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644); //读源文件 char buf[10]; while(1) { int read_count = read(source_fd, buf, sizeof(buf)); if(read_count == 0){ break; } printf("read_count = %d\n", read_count); //把buf写到target_fd里 int write_count = write(target_fd, buf, read_count); printf("write_count = %d\n", write_count); } //关闭 close(source_fd); close(target_fd); return 0; }

原来大小是14.

【Linux系统编程】lseek函数

标准输入是阻塞的。(等你输入完) 文件描述符为0。

#include<stdio.h> #include<string.h> #include<unistd.h> #include<pthread.h> #include<fcntl.h> int main(int argc, char* argv[]) { char buf[1024]; int read_count = read(0, buf, sizeof(buf)); printf("read_count = %d\n", read_count); return 0; }c

【Linux系统编程】lseek函数

#include<stdio.h> #include<string.h> #include<unistd.h> #include<pthread.h> #include<fcntl.h> int main(int argc, char* argv[]) { char buf[1024]; int read_count = read(0, buf, sizeof(buf)); printf("read_count = %d\n", read_count); write(1, buf, read_count); return 0; }

【Linux系统编程】lseek函数

设置成非阻塞(不等了,读不到)

#include<stdio.h> #include<string.h> #include<unistd.h> #include<pthread.h> #include<fcntl.h> int main(int argc, char* argv[]) { int fd = open("/dev/fd/0", O_RDWR | O_NONBLOCK);//设置非阻塞 char buf[1024]; int read_count = read(fd, buf, sizeof(buf));//参数改为fd printf("read_count = %d\n", read_count); write(1, buf, read_count); return 0; }

【Linux系统编程】lseek函数

【Linux系统编程】lseek函数

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/128410.html

(0)
上一篇 2025-08-31 19:26
下一篇 2025-08-31 19:33

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信