【linux基础I/O(1)】文件形貌符的本质&重定向的本质
前言“在Linux系统下,一切皆文件”,相信你也听过这句话,,那么怎样明白这句话呢?学会这篇文字,你就能明白了。
本章重点:
本篇文章着重讲解I/O的四个系统调用接口, 以及文件形貌符fd的熟悉与fd的本质, 最后讲解应该怎样明白Linux下一切皆文件这一说法.在此之前,会先复习一下C语言的文件相干的库函数。
1. 明白C语言的文件接口
起首C\C++程序会默认打开stdin,stdout和stderr三个尺度文件方便程序员直接举行读写.
但是显然有点不对劲, 我们平常使用printf和scanf时是从显示器中显示和从键盘输入, 是不是代表显示器和键盘在OS内部其实也可以看作文件?是的,向显示器打印和向磁盘写入无本质区别!
C语言打开文件的方式: fopen
C语言的读取: fread, fscanf, fgets
C语言的写入: fwrite, fprintf, fputs
fopen的返回值和三个尺度文件范例都是FILE*
2. 利用文件的系统调用接口
每个语言都有一套自己的文件利用函数,但不管上层语言怎样变革,它都是封装了系统调用,所以文件的系统调用很紧张!
一共四个函数:
1.open: 打开文件
2.close: 关闭文件
3.write: 向文件写入
4.read: 从文件中读取
2.1 open函数详解
https://i-blog.csdnimg.cn/direct/85259feb91ba493c87b7bebc89b29e54.png
open函数的解释如下:
https://i-blog.csdnimg.cn/direct/c28717fe84fc47049d5d2dc5c367bb87.png
这个flag比力特殊,虽然它是整型,但是内部却当作了位图在使用,即转达过来的选项会被当作位图中的不同位,通过判断某位是否为1来查看是否有这个选项.
open的选项(实际上是宏界说的整数)
https://i-blog.csdnimg.cn/direct/417473533d6b4e2ba54633fda178164e.png
open的用法: 多个选项用或|分割
int fd = open("/home/cc/test.txt",O_WRONLY | O_CREAT);
2.2 close函数详解
https://i-blog.csdnimg.cn/direct/b36c5aebc33c4cb68e5e2d46bcb34b82.png
close函数很简单,意思就是关闭文件形貌符fd对应的文件, 调用成功返回0.
2.3 write函数详解
https://i-blog.csdnimg.cn/direct/d0de78cea26d41e5904e07c376dbae49.png
write是向文件形貌符fd对应的文件中写入数据, 数据的泉源是buf, 要写入的字节数是count, 调用成功返回写入到文件中的字节数.
write的一般用法:
char* buffer = "abcdef";
int fd = open("/home/cc/text.txt",O_WRONLY);
write(fd,buffer,sizeof(buffer));
2.4 read函数详解
https://i-blog.csdnimg.cn/direct/a14444a0c3f443a1b767e3c750435534.png
read是从文件形貌符fd对应的文件中读取数据, 将数据读取到buf中,要读取的长度是count, 调用成功返回读取到的字节数.
read的一般用法:
char buffer;
int fd = open("/home/cc/text.txt",O_WRONLY);
ssize_t n = read(fd,buffer,sizeof(buffer));
if(n > 0)
buffer = '\0';//将字符串变成C语言风格,以\0结尾
3. 文件形貌符fd详解
我们知道文件形貌符是一个整数,那么它是否有什么规律呢?请看下面的代码:
int fd1 = open("/home/kwy/text1.txt",O_WRONLY | O_CREAT);
int fd2 = open("/home/kwy/text2.txt",O_WRONLY | O_CREAT);
int fd3 = open("/home/kwy/text3.txt",O_WRONLY | O_CREAT);
int fd4 = open("/home/kwy/text4.txt",O_WRONLY | O_CREAT);
printf("%d, %d, %d, %d",fd1,fd2,fd3,fd4);
会发现fa1,2,3,4的整数值分别是:
3,4,5,6,这是为什么?必要回答两个问题:
1. 0号1号和2号形貌符去哪儿了?
2. 文件形貌符的增长规律是什么?
起首, 在最开始说过C/C++程序会默认打开stdin, stdout, stderr三个尺度文件,所以其实0,1,2号文件形貌符就是这三个尺度文件.
其次, 0,1,2被使用后, 后面的文件形貌符会从3开始, 依次+1, 一共创建到6号形貌符,若此时将3号文件形貌符关闭,下次打开文件对应的形貌符就是3,而不是7!
可以使用下面的代码来验证第一个猜想:
//向屏幕打印信息
const char* str = "abcdef";
write(1, str, strlen(str));
//从屏幕读取信息
char buffer;
int n = read(0, buffer, sizeof(buffer));
if(n > 0)
buffer = '\0';
4. 文件形貌符的内核本质
进程想要访问某个文件的条件是打开文件,在利用系统内大概会有很多个打开的文件,OS为了维护这些资源,必要对它举行管理,会为每个打开的文件创建struct file布局体, 再用链表将这些布局体连接起来.
https://i-blog.csdnimg.cn/direct/f9d4f97f7d7346d6a878c3cb6c0417f1.png
这是文件在OS内部的管理体系,而每个进程都要知道自己打开了哪些文件, 所以进程PCB中会保存一张文件形貌符表(本质是布局体指针),这个表中存放了这个进程打开的所有文件!
https://i-blog.csdnimg.cn/direct/d4e4c08f53bf4668a534ad1243bc252f.png
从这个图中可以看见, 文件形貌符的本质其实就是数组的下标,每次打开文件会去数组中扫描,找到近来的没有被使用的下标!
5. 怎样明白Linux下一切皆文件?
起首,底层不同的硬件如磁盘,显卡,键盘等肯定对应了不同的利用方法,但这些设备的核心功能就是读写,也就是I/O.
https://i-blog.csdnimg.cn/direct/cee8531ea0af467e8d7b2a3ac2ce3543.png
利用系统会为每一个底层硬件创建struct file布局体,此布局体中肯定包罗了两个函数指针,分别指向这个硬件对应的读方法和写方法.
所以当我们使用键盘或打开显示器时,就会有对应的指针指向对应的谁人方法。
所以当我们使用键盘时,0S就会去找到谁人structfile,而且找到里面的方法调用。当我们从 struct file 的角度向上看时,就不用关心底层外设的差异了,利用它们的方法都是:read/write的函数指针,在上层我们看到是所有设备就叫做 一切皆文件!
6. 明白输出输入重定向
根据上面的推论,如果我先把1号形貌符关闭了,再打开一个文件,它的形貌符就应该是1,此时再举行输出会发现什么?
int main()
{
close(1);
int fd = open("log.txt",O_WRONLY | O_CREAT | O_TRUNC, 0666);
printf("fd: %d\n",fd);
fprintf(stdout,"hello fprintf,我是一号文件描述符\n");
return 0;
}
https://i-blog.csdnimg.cn/direct/044db6ffb7b34a409c54819ef999e52f.png
两个现象,第一个确实如刚刚所说的新打开的文件的形貌符就是1,而且此时使用printf输出也不会输出到屏幕使用fprintf向stdout也不会输出到屏幕而是输出到文件log.txt中.说明stdout只认文件形貌符1,不管1此时还是不是尺度输出,printf函数也是如此.
结论:重定向本质就是在OS内部修改fd对应的内容指向.
https://i-blog.csdnimg.cn/direct/c5a94749e43842dea31b483b57fe2fea.png
7. 重定向的系统调用
如果每次写重定向都要先关闭一个文件,再来利用未免有些贫困了,可以直接使用系统调用dup或dup2函数.
https://i-blog.csdnimg.cn/direct/049fe6e34f8d4408b60a47af2f721bbd.png
我们一般都使用dup2,它的意思是把原本写入到newfile 文件的内容,重定向到 oldfile 文件中!最终和oldfd形貌符是一样的。比如如今想把本来应该打印在显示器(1号形貌符)的信息打印在log.txt中(3号形貌符),应该如许使用:
open("log.txt",O_WRONLY | O_CREAT);
dup2(3,1);
8. 总结
文件形貌符是学习Linux下I/O的关键,而基础IO的知识将会一直陪伴我们到学习Linux网络和高级IO,把握文件形貌符fd的本质对后续的学习至关紧张!
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]