基础IO(一切皆文件)

目录

1.重定向补充

为什么存在一个标准错误+printf、perror?cout/cerr

如果stderr和stdout打印到同一文件?

源代码

2.理解一切皆文件


1.重定向补充

复制代码
[user1@iZ5waahoxw3q2bZ 26-5-12]$ ./a.out 1 > log.txt
[user1@iZ5waahoxw3q2bZ 26-5-12]$ ll
total 20
-rwxrwxr-x 1 user1 user1 9104 May 12 14:37 a.out
-rw-rw-r-- 1 user1 user1   24 May 12 14:38 log.txt
-rw-rw-r-- 1 user1 user1  185 May 12 14:36 stream.cc
[user1@iZ5waahoxw3q2bZ 26-5-12]$ cat log.txt
hello cout
hello printf

重定向完整写法是1重定向到log.txt中,一般会把1进行省略

复制代码
[user1@iZ5waahoxw3q2bZ 26-5-12]$ cat stream.cc
#include<cstdio>
#include<iostream>

int main()
{
    //向标准输出进行打印,stdout,cin-》 1
    std::cout<<"hello cout"<<std::endl;
    printf("hello printf\n");

    //向标准错误进行打印,stderr,cerr-》2
    std::cerr<<"hello cerr"<<std::endl;
    fprintf(stderr,"hello stderr\n");
    return 0;
}

[user1@iZ5waahoxw3q2bZ 26-5-12]$ g++ stream.cc
[user1@iZ5waahoxw3q2bZ 26-5-12]$ ./a.out
hello cout
hello printf
hello cerr
hello stderr
[user1@iZ5waahoxw3q2bZ 26-5-12]$ ./a.out > log.txt
hello cerr
hello stderr
[user1@iZ5waahoxw3q2bZ 26-5-12]$ cat log.txt
hello cout
hello printf

为什么我们对应的标准输出写到了log.txt里面,而标准错误却依然在显示器文件上进行打印

原因是因为我们在对应输出的时候,虽然我们对应的标准输出和标准错误都指向同一个文件。

但当我们进行重定向时,实际上还是把1重定向到新文件,即把新打开的文件描述符的struct_file的地址拷贝到1里面,把1重定向了。可是我们2依旧指向标准错误往显示器上打印。

复制代码
[user1@iZ5waahoxw3q2bZ 26-5-12]$ ./a.out 1>log.normal 2>log.error
[user1@iZ5waahoxw3q2bZ 26-5-12]$ ll
total 28
-rwxrwxr-x 1 user1 user1 9248 May 12 14:42 a.out
-rw-rw-r-- 1 user1 user1   24 May 12 14:48 log.error
-rw-rw-r-- 1 user1 user1   24 May 12 14:48 log.normal
-rw-rw-r-- 1 user1 user1   24 May 12 14:43 log.txt
-rw-rw-r-- 1 user1 user1  317 May 12 14:42 stream.cc
[user1@iZ5waahoxw3q2bZ 26-5-12]$ cat log.normal
hello cout
hello printf
[user1@iZ5waahoxw3q2bZ 26-5-12]$ cat log.error
hello cerr
hello stderr

所以我们指向明确就可以正确地进行重定向了!

为什么存在一个标准错误+printf、perror?cout/cerr

可以通过重定向能力,把常规消息和错误消息进行分离

方便我们日志的形成

如果stderr和stdout打印到同一文件?

复制代码
[user1@iZ5waahoxw3q2bZ 26-5-12]$ rm log*
[user1@iZ5waahoxw3q2bZ 26-5-12]$ ll
total 16
-rwxrwxr-x 1 user1 user1 9248 May 12 14:42 a.out
-rw-rw-r-- 1 user1 user1  317 May 12 14:42 stream.cc
[user1@iZ5waahoxw3q2bZ 26-5-12]$ ./a.out 1>log.normal 2>log.normal
[user1@iZ5waahoxw3q2bZ 26-5-12]$ cat log.normal
hello cerr
hello stderr

为什么这样只显示标准错误?

第一次是标准输出写进去,第二次打开就清空了然后再将标准错误写入。

1.追加重定向

复制代码
[user1@iZ5waahoxw3q2bZ 26-5-12]$ ./a.out 1>log.normal 2>>log.normal
[user1@iZ5waahoxw3q2bZ 26-5-12]$ cat log.normal
hello cout
hello printf
hello cerr
hello stderr

2.

2>&1----把1中的内容再写到2里面

复制代码
[user1@iZ5waahoxw3q2bZ 26-5-12]$ rm log*
[user1@iZ5waahoxw3q2bZ 26-5-12]$ ll
total 16
-rwxrwxr-x 1 user1 user1 9248 May 12 14:42 a.out
-rw-rw-r-- 1 user1 user1  317 May 12 14:42 stream.cc
[user1@iZ5waahoxw3q2bZ 26-5-12]$ ./a.out 1>log.normal 2>&1
[user1@iZ5waahoxw3q2bZ 26-5-12]$ cat log.normal
hello cout
hello printf
hello cerr
hello stderr

源代码

struct file * fd_array[NR_OPEN_DEFAULT];文件描述符表内对应的数组

保存的是一个进程的struct file *也就是一个文件

atomic t → f_count;//引用计数

f_flags打开文件时读写权限

f_mode打开的文件对应的权限

f_pos当前读写一个文件对应的读写位置

进程有自己的管理列表,文件有自己的管理列表。进程和文件的管理是解耦的,用文件描述符表产生关联。

操作系统管理内存的时候,也不是把内存整体使用的。把操作系统空间划分为以块为单位的,也就是以4KB的大小划分成块。所以一个4GB的内存,在操作系统中有4GB/4KB个数据页构成的。

所以在操作系统内一定存在很多的内存块。有的内存块被申请被占用被清理等。。。

操作系统要管理这些内存块---先描述再组织

将来为内存也有一个管理内存的数据结构叫做struct_page,只要找到内存对应的struct_page就能找到对应的数据块。

可以通过struct_file找到对应的内核缓冲区

struct_file是操作系统内打开的文件,但是文件的一些相关的硬属性并没有直接在这个file里存,在另外一个inode。可以通过file间接找到文件的属性和文件的缓冲区。

2.理解一切皆文件

首先,在windows中是文件的东西,它们在linux中也是文件;其次⼀些在windows中不是文件的东西,比如进程、磁盘、显示器、键盘这样硬件设备也被抽象成了文件,你可以使用访问文件的方法访问它们获得信息;甚至管道,也是文件;将来我们要学习网络编程中的socket(套接字)这样的东西,使用的接口跟文件接口也是⼀致的。

这样做最明显的好处是,开发者仅需要使用⼀套API和开发工具,即可调取Linux系统中绝大部分的资源。举个简单的例子,Linux中几乎所有读(读文件,读系统状态,读PIPE)的操作都可以用read函数来进行;几乎所有更改(更改文件,更改系统参数,写PIPE)的操作都可以用write函数来进行。

struct device

{

//type

//status

//其他属性

list_head

}

每个外设都有对应struct device

对设备的管理变成了对链表的增删查改

struct_file

属性 文件缓冲区

void(*read)(int fd,char*,int);---指向磁盘的读

void(*write)(int fd,char*,int);---- 写

struct_file往上一切皆文件

在系统中访问任何设备,只要提供文件描述符,可以不用关心底层硬件的差异,直接去使用函数内部的指针来访问

VFS virtual file system 虚拟文件系统

struct_file基类

访问设备,都是通过函数指针指向的方法进行访问
的!
函数指针类型命名,参数,都一样!

不就是C版本的多态吗!

感谢你的观看,期待我们下次再见!

相关推荐
d111111111d1 小时前
MQTT+STM32+云平台+AT命令的编写
服务器·笔记·stm32·单片机·嵌入式硬件·算法
铁皮哥1 小时前
【力扣题解】LeetCode 25. K 个一组翻转链表
java·数据结构·windows·python·算法·leetcode·链表
Irissgwe2 小时前
四、进程控制(进程创建与终止)
linux·c++·进程·系统编程·fork·进程创建·进程终止
宵时待雨2 小时前
linux笔记归纳5:进程控制
linux·运维·笔记
代钦塔拉2 小时前
第一篇:工业级 C++/Qt 项目头文件包含原则:告别循环依赖与编译玄学
开发语言·c++·qt
洛水水2 小时前
【力扣100题】29. 对称二叉树
算法·leetcode·职场和发展
Severus_black2 小时前
【初阶数据结构】C语言实现堆(Heap),巨详细!
c语言·数据结构
夏日听雨眠2 小时前
LInux(gcc处理器,库文件,动静态库)
linux·运维·服务器
大熊背2 小时前
近期遇到的一些问题总结(四)
算法·拍照·白平衡·isp pipeline