Linux系统提供的操作文件的底层补充总结及进程替换

张开发
2026/4/17 4:55:42 15 分钟阅读

分享文章

Linux系统提供的操作文件的底层补充总结及进程替换
Linux系统提供的操作文件的底层文件描述符内核中的函数open read write close都是系统调用编号为2编写内核代码时实现的功能留给用户可以调用产生中断陷入内核切换到内核态如c语言中访问文件的方法 库函数fopen() 其本质就是通过系统调用open()fclose()对文件的操作方法打开文件读、写关闭文件示例#includestdio.h #includestdlib.h #includeunistd.h #includestring.h #includefcntl.h int main() { /* int fd open(./file.txt,O_WRONLY|O_CREAT,0600);//./可以不写默认当前位置该文件不存在要创建O_CREAT若文件已存在会自动忽略O_CREAT只读O_RDONLY 读写O_RDWR按位或在一起每一个标志对应一个二进制位这个位置置1表示该操作有被设置权限0600属主自己可读可写8进制 if(fd -1) { printf(open failed\n); exit(1); } write(fd,hello,5);//5为写入的字符数 close(fd); */ int fd open(file.txt,O_RDONLY);//文件已存在权限已经确定下来就不用再给出 if(fd -1) { printf(open failed\n); exit(1); } char buff[128]{0}; read(fd,buff,127);//读取fd文件中的数据存到buff中期望读取127个具体能读多少取决于fd文件中的数据量 printf(buff%s\n,buff); close(fd); exit(0); }4. fd表示正在打开的文件 0为键盘 1为屏幕文件打开之后会有一张文件表记录打开的文件程序启动默认打开前三个文件0stdin标准输入1stdout标准输出2stderr标准错误输出3file.txt...复制一个文件#includestdio.h #includestdlib.h #includeunistd.h #includestring.h #includefcntl.h int main(int argc,char* argv[]) { if(argc ! 3) { printf(arg err,示例 ./mycp xx xx\n); exit(1); } char* s_name argv[1]; char* t_name argv[2]; int fdr open(s_name,O_RDONLY); if(fdr -1) { printf(原文件%s,打开失败\n,s_name); exit(1); } int fdw open(t_name,O_WRONLY|O_CREAT,0600); if(fdw -1) { printf(新文件%s,打开/创建失败\n,t_name); exit(1); } printf(fdr%d,fdw%d\n,fdr,fdw);//打印出来为3和4每open一个对应文件表的下标 char buff[128] {0}; int num 0; while((num read(fdr,buff,128)) 0) { write(fdw,buff,num); } close(fdr); close(fdw); exit(0); }#includestdio.h #includestdlib.h #includeunistd.h #includestring.h #includefcntl.h int main() { int fd open(file.txt,O_RDONLY); if(fd -1) { exit(1); } pid_t pid fork(); if(pid -1) { exit(1); } //int fd open(file.txt,O_RDONLY); //if(fd -1) //{ //exit(1); //} //若将打开文件放在fork()之后父进程和子进程各自拥有各自的struct file偏移量互不影响 if(pid 0) { char buff[128] {0}; read(fd,buff,1); printf(child read:%s\n,buff); sleep(1); read(fd,buff,1); printf(child read:%s\n,buff); } else { char buff[128] {0}; read(fd,buff,1); printf(parent read:%s\n,buff); sleep(1); read(fd,buff,1); printf(parent read:%s\n,buff); } //偏移量会自动向后移动 //父进程打开的文件fork后父子进程都可以共享访问文件偏移量是共享的 close(fd); }#includestdio.h #includestdlib.h #includeunistd.h #includestring.h #includefcntl.h int main() { printf(A);//放在缓冲区中 write(1,B,1); fork(); //char buff[128] {0}; //read(0,buff,127); //printf(buff%s\n,buff); //write(1,hello\n,6); //printf中封装了write()系统调用 //printf 库函数-write() 系统调用 exit(0); }进程替换 exec系列fork()复制进程exec()将复制出来的进程替换为一个全新的进程可以将一些主性信息继承过来系统调用 execve库函数execlexeclpexecvexecleexecvp库函数本质也是调用execve实现的ps方便验证结果#includestdio.h #includestdlib.h #includeunistd.h #includestring.h #includefcntl.h int main() { printf(man pid%d\n,getpid()); execl(/usr/bin/ps,ps,-f,NULL);//路径加名称程序启动之后的主函数需要传的参数当前程序的名字一般为主函数的第一个参数传完之后空指针结尾执行成功之后不返回因为执行成功之后会将新进程启动新进程会从主函数的第一行代码开始执行执行失败才返回 //若执行成功当前main会被替换为psID不变 printf(execl err\n); //若执行失败则执行原有程序的代码 exit(0); }

更多文章