360免费建站永久免费,营销手段,完美代码的网站,网页制作模板简易目录
文件内核对象
文件描述符的分配规则
重定向
重定向的概念
dup2系统调用
输出重定向
追加重定向
输入重定向
stderr解析
重定向到同一个文件中
分离常规输出和错输出 文件内核对象
上篇文章中我们介绍到了操作系统中的文件#xff0c;操作系统为了方…目录
文件内核对象
文件描述符的分配规则
重定向
重定向的概念
dup2系统调用
输出重定向
追加重定向
输入重定向
stderr解析
重定向到同一个文件中
分离常规输出和错输出 文件内核对象
上篇文章中我们介绍到了操作系统中的文件操作系统为了方便管理进程打开的每个文件都会给每个文件创建一个内核对象(struct file)。但是每个进程可能打开多个进程因此操作系统会形成一个数组数组中的每个元素为文件内核对象指针指向当前进程打开的每个文件数组的下标就代表一个打开的文件对文件进行操作就是对数组的下标进行操作。打开的文件会加载在内存中每个文件也都会有一段内存空间文件缓冲区打开文件会对文件进行操作一般就是读操作和写操作因此每个文件内核对象中一定含有这三种信息 打开文件的属性进行文件操作的方法集文件的内存空间文件缓冲区 总结 不能对磁盘中的内存进行操作只能先将文件加载到内存中。对文件进行读数据和写数据都先要将文件加载到内存中当文件不在内存中时会造成缺页中断操作系统自动会将文件加载到内存中。数据的读写本质是将内核缓冲区中的数据进行来回拷贝。 文件描述符的分配规则 1 #includestdio.h2 #includesys/types.h3 #includesys/stat.h4 #includefcntl.h5 #includeunistd.h6 #includestring.h7 #define FILE_NAME log.txt8 int main()9 {10 11 char buffer[1024];12 ssize_t s read(0,buffer,1024);13 if(s0) 14 {15 buffer[s-1]0;16 printf(echo# %s\n,buffer);17 write(1,buffer,strlen(buffer));18 }26 return 0;27 } 可以直接使用0和1文件描述符进行键盘和显示器的读写。 #includestdio.h2 #includesys/types.h3 #includesys/stat.h4 #includefcntl.h5 #includeunistd.h6 #includestring.h 7 #define FILE_NAME log.txt8 int main()9 {10 int fd open(FILE_NAME,O_CREAT|O_WRONLY|O_TRUNC,0666);11 if(fd0)12 {13 perror(open);14 return 0;15 } 16 printf(fd:%d\n,fd);close(fd);17 return 0;18 }上篇文章我们说过进程会默认打开三个流stdin、stdout、stderr分别为012。 文件描述符的分配规则寻找最小的没有被使用的数据的位置分配给指定的打开文件。 重定向
重定向的概念 改变原来系统命令的默认执行方式Linux重定向是指修改原来默认的一些东西对原来系统命令的默认执行方式进行改变比如说简单的我不想看到在显示器的输出而是希望输出到某一文件中就可以通过Linux重定向来进行这项工作。 先执行一段代码看现象 #includestdio.h2 #includesys/types.h3 #includesys/stat.h4 #includefcntl.h5 #includeunistd.h6 #includestring.h7 #define FILE_NAME log.txt8 int main()9 {10 11 close(1);12 int fd open(FILE_NAME,O_CREAT|O_WRONLY|O_TRUNC,0666);13 if(fd0)14 {15 perror(open);16 return 0;17 }18 printf(fd : %d \n,fd);19 printf(stdout-fd : %d \n,stdout-_fileno);fflush(stdout);close(fd)return 0;} 当我们不使用fflush刷新stdout时显示器和新打开的文件都不会输出我们打印的内容现象对应我们的第一张图片。使用fflush刷新stdout时显示器不会输出我们的内容但是新打开的文件中含有我们输出的内容。 现象的解释进程运行是会打开我们的stdin、stdout、stderr对应的文件描述符为012。当我我们关闭1即关闭显示器。当新打开文件时根据文件描述符的分配规则文件描述符为1但是printf、fprintf底层只认文件描述符1但是此时的文件描述符已经不是stdout而是新打开的文件因此输出到新打开的文件中。 1 #includestdio.h2 #includesys/types.h3 #includesys/stat.h4 #includefcntl.h5 #includeunistd.h6 #includestring.h7 #define FILE_NAME log.txt8 int main()9 {10 11 close(0);12 char buffer[1024];13 int fd open(FILE_NAME,O_RDONLY); 14 if(fd0)15 {16 perror(open);17 return 0;18 }19 fread(buffer,1,sizeof(buffer),stdin);20 printf(%s\n,buffer);close(fd)return 0;} 根据上面的原理我们可以关闭0即关闭从键盘输入打开新文件此时新文件的文件描述符为0从新打开的文件中读取数据输入。
dup2系统调用
通过上面的代码我们可以实现输入、输出重定向但是需要我们手动关闭键盘或者显示器非常的麻烦Linux中提供了系统调用方便我们进行重定向。 当调用dup函数时内核在进程中创建一个新的文件描述符此描述符是当前可用文件描述符的最小数值这个文件描述符指向oldfd所拥有的文件表项。dup2和dup的区别就是可以用newfd参数指定新描述符的数值如果newfd已经打开则先将其关闭。如果newfd等于oldfd则dup2返回newfd, 而不关闭它。dup2函数返回的新文件描述符同样与参数oldfd共享同一文件表项。 输出重定向
#includestdio.h2 #includesys/types.h3 #includesys/stat.h4 #includefcntl.h5 #includeunistd.h6 #includestring.h7 #define FILE_NAME log.txt8 int main()9 {10 int fd open(FILE_NAME,O_CREAT|O_WRONLY|O_TRUNC,0666);11 if(fd0)12 {13 perror(open);14 return 0;15 }16 dup2(fd,1);17 printf(fd : %d \n,fd);18 printf(stdout-fd : %d\n ,stdout-_fileno);19 printf(hello Linux\n);20 fprintf(stdout,hello world\n); close(fd);return 0;} 使用系统调用进行重定向时并不会像我们一样关闭键盘或者显示器而是创建新的文件描述符然后让键盘或者显示器的文件描述符和键盘、显示器断开和我们新打开的文件建立联系此时这个文件就含有两个文件描述符使用引用计数进行关闭文件。 追加重定向
#includestdio.h2 #includesys/types.h3 #includesys/stat.h4 #includefcntl.h5 #includeunistd.h6 #includestring.h7 #define FILE_NAME log.txt8 int main()9 {10 int fd open(FILE_NAME,O_CREAT|O_WRONLY|O_APPEND,0666);11 if(fd0)12 {13 perror(open);14 return 0;15 }16 dup2(fd,1);17 printf(fd : %d \n,fd);18 printf(stdout-fd : %d\n ,stdout-_fileno);19 printf(hello Linux\n);20 fprintf(stdout,hello world\n); close(fd);return 0;} 输入重定向 #includestdio.h2 #includesys/types.h3 #includesys/stat.h4 #includefcntl.h5 #includeunistd.h6 #includestring.h7 #define FILE_NAME log.txt8 int main()9 {10 // int fd open(FILE_NAME,O_CREAT|O_WRONLY|O_APPEND,0666);11 int fd open(FILE_NAME,O_RDONLY); 12 if(fd0)13 {14 perror(open);15 return 0;16 }17 dup2(fd,0);18 // printf(fd : %d \n,fd);19 // printf(stdout-fd : %d\n ,stdout-_fileno);20 // printf(hello Linux\n);21 // fprintf(stdout,hello world\n);22 char buffer[1024];23 fread(buffer , 1,1024,stdin);24 printf(%s,buffer);close(fd);return 0;} stderr解析
上篇文章我们提到stdout和stderr都代表显示器流即往显示器文件中打印。
#includestdio.h
int main()
{fprintf(stdout,hello stdout\n);fprintf(stderr,hello stderr\n);return 0;
} 但是我们进行重定向时只会将stdout进行重定向到文件中 stderr会在进程中保留。 因为fprintf底层只认文件描述符1因此stderr不会被重定向。
重定向到同一个文件中 分离常规输出和错输出 进程运行时难免发生错误输出错误信息为了和常规信息进行区别错误信息和常规信息分别独占一个显示器文件夹我们只需要查看错误信息的显示器文件夹即可发现程序的报错信息。 今天对Linux下文件重定向的分享到这就结束了希望大家读完后有很大的收获也可以在评论区点评文章中的内容和分享自己的看法个人主页还有很多精彩的内容。您三连的支持就是我前进的动力感谢大家的支持