C++文件

文章详细阐述了stdout和stderr在程序输出中的不同,它们分别对应显示器文件的两个通道。同时,通过代码示例展示了如何重定向输出到不同文件。文章还深入探讨了Linux文件系统,包括磁盘结构、CHS寻址、LBA寻址、inode和块组的概念,以及文件内容和属性的分离存储方式。
摘要由CSDN通过智能技术生成

stdout/stderr

stdout/stderr有啥区别呢??

1和2对应的都是显示器文件,但是他们两个是不同的,如同认为,同一个显示器文件,被打开了两次!

以下面这段代码为例。

#include <iostream> #include <stdio.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <errno.h> void myperror(const char *msg) { fprintf(stderr, "%s: %s\n", msg, strerror(errno)); } int main() { //stdout -> 1 printf("hello printf 1\n"); fprintf(stdout,"hello fprintf 1\n"); // stderr -> 2 errno = 1; perror("hello perror 2"); //stderr const char *s1 = "hello write 1\n"; write(1, s1, strlen(s1)); const char *s2 = "hello write 2\n"; write(2, s2, strlen(s2)); // cout -> 1 std::cout << "hello cout 1" << std::endl; // cerr -> 2 std::cerr << "hello cerr 2" << std::endl; return 0; }

运行结果

[hang@VM-4-12-centos day11]$ make g++ -o myfile myfile.cc [hang@VM-4-12-centos day11]$ ./myfile hello printf 1 hello fprintf 1 hello perror 2: Operation not permitted hello write 1 hello write 2 hello cout 1 hello cerr 2 [hang@VM-4-12-centos day11]$ ./myfile >log.txt hello perror 2: Operation not permitted hello write 2 hello cerr 2

分开打印到两个文件中

[hang@VM-4-12-centos day11]$ ./myfile >ok.txt 2>err.txt [hang@VM-4-12-centos day11]$ cat ok.txt hello write 1 hello printf 1 hello fprintf 1 hello cout 1 [hang@VM-4-12-centos day11]$ cat err.txt hello perror 2: Operation not permitted hello write 2 hello cerr 2 [hang@VM-4-12-centos day11]$

合起来打印到一个文件中

[hang@VM-4-12-centos day11]$ ./myfile >ok.txt 2>&1 [hang@VM-4-12-centos day11]$ ls Makefile myfile myfile.cc ok.txt [hang@VM-4-12-centos day11]$ cat ok.txt hello perror 2: Operation not permitted hello write 1 hello write 2 hello printf 1 hello fprintf 1 hello cout 1 hello cerr 2 [hang@VM-4-12-centos day11]$ [hang@VM-4-12-centos day11]$ cat < ok.txt >err.txt [hang@VM-4-12-centos day11]$ ls err.txt Makefile myfile myfile.cc ok.txt [hang@VM-4-12-centos day11]$ cat err.txt hello perror 2: Operation not permitted hello write 1 hello write 2 hello printf 1 hello fprintf 1 hello cout 1 hello cerr 2

perror

errno = 1; perror("hello perror 2"); //stderr

#include <iostream> #include <stdio.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <errno.h> void myperror(const char *msg) { fprintf(stderr, "%s: %s\n", msg, strerror(errno)); } int main() { int fd = open("log.txt", O_RDONLY); if(fd < 0) { myperror("open"); return 1; } return 0; }

电脑上的文件可以分为两类:被进程打开的,未被打开的。

前者被进程加载到内存中去,后者则存在于磁盘(磁盘级文件)

文件

站在单个文件的角度:这个文件在哪里?有多大?其他属性是什么?.........

站在系统的角度:一共有多少文件?各自的属性存储在哪里?如何快速找到?还可以存储多少文件?..........

文件系统的目的:如何对磁盘文件进行分类的存储,用来支持更好的存取!!

磁盘–永久性存储介质-SSD,U盘,flash卡,光盘,磁带

内存--掉电易失介质

磁盘是一个外设,是我们计算机唯一一个机械设备!这样注定了它的速度很慢,OS会有一些提速方式。

浅浅了解一下磁盘。

磁盘盘片,磁头,伺服系统,音圈马达...........

磁盘盘面会存储数据,由于计算机只认识二进制。联想到磁铁的正极和负极,就可以明白了;

向磁盘写入,本质就是改变磁盘上的正负极。

磁盘的基本结构

注意一个扇面的大小是512字节(通常)(磁盘存储数据的基本单位)。

在物理上,如何把数据写入到指定的扇区里?

如何找到一个扇区(CHS寻址)

1.在哪一个面上~(对应的就是哪一个磁头)

2.在哪一个磁道(柱面)上

3.在哪一个扇区上

如果我们有了chs,就能找到任意一个扇区,那么所有扇区我们就都能找到了!

通过将磁盘的存储方式进行逻辑化推演成线性结构。访问一个扇区,其实就由一个块组成的数组。计算机通过LBA寻址方式进行定位,然后转换成CHS进行磁盘定位。

对磁盘的管理采用分而治之 的思想,将整体拆分进行规划。

最终对磁盘的管理就精确到了一个小分区的管理。

块组组成

Linux在磁盘上存储文件的时候,将内容和属性是分开存储的!

Super Block:简单来说,就是文件系统的属性信息。复杂一些:存放文件系统本身的结构信息。记录的信息主要有:bolck 和 inode的总量,未使用的block和inode的数量,一个block和inode的大小,最近一次挂载的时间,最近一次写入数据的时间,最近一次检验磁盘的时间等其他文件系统的相关信息。Super Block的信息被破坏,可以说整个文件系统结构就被破坏了。

说人话:是整个分区的文件系统信息,不是单个块组的(不长眼的磁头)

Data blocks:多个4KB(扇区*8)大小的集合﹐保存的都是特定文件的内容

inode Table: inode是一个大小为128字节的空间,保存的是对应文件的属性

该块组内,所有文件的inode空间的集合,需要标识唯一性,每一个inode块,都要有一个inode编号!一般而言一个文件,一个inode,一个inode编号

BlockBitmap:假设有10000+个blocks,10000+比特位:比特位和特定的block是一一对应的,其中比特位为1,代表该block被占用,否则表示可用!

inode Bitmap:假设有10000+个inode节点,就有10000+个比特位,比特位和特定的inode是一一对应的。其中bitmap中比特为为1,代表该inode,被占用,否则表示可用!

GDT:块组描述符,这个块 组多大,已经使用了多少了,有多少个inode,已经行用了多少个,还剩多少,一共有多少个block,使用了多少....

BootBlock:启动块

这些区域让一个文件的信息可追溯,可管理。

将块组分割成上面的内容,并且写入相关的管理数据。其他块组类似,整个分区就被写入了文件信息系统!

我们可以发现的是,Linux在磁盘上存储文件的时候,是将内容和属性分开存储的!!!

磁盘的基本的单位扇区(512字节),但是操作系统(文件系统)和磁盘进行IO的基本单位是4kb(block大小,这也是磁盘被称为块设备的原因)。

为什么不以512字节为基本单位?

1.太小了,有可能会导致多次I0,进而导致效率的降低!

2.如果操作系统使用和磁盘一样的大小,万一磁盘基本大小变了的话,OS的源代码要不要改呢﹖硬件和软件(OS)进行解耦!

我们讲块组分割成为上面的内容--->>并且写入相关的管理数据->每一个块组都这么干---->>整个分区就被写入了文件系统信息!(相当于格式化)

1.那些block属于同一个文件?

2.找到文件,只要找到文件对应的inode编号,就能找到改文件的inode属性集合,可是,文件的内容?

data block中,不是所有的data block只能存文件数据。也可以存其他块的块号!!

寻找文件,首先通过inode编号---->>> 找到分区特定的块组(block group)---->>inode---->属性---->内容

我们通过依托于目录结构来知道inode编号!!

linux中,inode属性里面,没有文件名这样的说法!

分区格式化------->>>>在磁盘写入文件系统!

inode是固定的,datablock是固定的!

那么就有可能出现还有内存空间,但是却无法新建文件的现象。

目录是文件吗﹖是->有自己的inode,有自己的data block。在data block中存储的是文件名 ------inode编号的映射关系(互为key值)。

文件名对应的是用户,inode对应的是文件系统。

那这里我们又要想到一个东西,

进入目录所需权限:x

创建文件所需权限:w

显示文件名与属性:r

新增的

我们需要在目录文件中找到我们的对应的映射关系,那么如何找到目录文件呢??是需要到目录文件的上级目录下去寻找的。我们操作系统在寻找文件时,会在操作系统内核中生成一个目录树。这就是我们第一次查找文件时比较慢的原因。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值