type
status
summary
date
slug
tags
category
icon
password
我们先做一个小实验:
我们在c代码中先close(1)再open一个文件,使用write函数向文件描述符为一的文件输入内容(其实就是stdout),然后编译运行我们会发现,我们本来应该打印在显示器伤的内容出现在了文件中
这个现象其实就是一种重定向
这里的O_TRUNC标志就是如果文件已经存在就把文件的大小设置为零,这个标志一般用在,不需要以前的内容,像重新编写文件内容的时候
其实本质上就是在filestruct数组中如果write的文件被关闭默认指向其他下标最小的一个没有被使用的文件进行写入
那我们的系统中有没有这样的接口能使得我们进行快速的重定向呢?
答案是有的:dup2(其实英文全称是duplicate是复制的意思)
dup2
函数是一个用于文件描述符操作的函数,它定义在<unistd.h>
头文件中。dup2
函数的主要作用是将一个文件描述符复制到另一个文件描述符,并且可以选择性地关闭目标文件描述符(如果它已经打开)。函数原型如下:
参数
oldfd
:这是源文件描述符,即你想要复制的那个文件描述符。
newfd
:这是目标文件描述符,即你想要将oldfd
复制到的那个文件描述符。
返回值
- 成功时,返回新的文件描述符(通常与
newfd
相同),并且该文件描述符现在引用与oldfd
相同的文件、管道或套接字。
- 失败时,返回-1,并设置
errno
以指示错误原因。
功能
- 如果
newfd
已经打开,dup2
会先关闭它,然后再复制oldfd
到newfd
。
- 如果
oldfd
和newfd
相同,dup2
会成功返回newfd
,但不做任何改变。
- 如果
oldfd
不是一个有效的文件描述符,或者由于某些原因(如资源限制)无法复制文件描述符,dup2
会失败。
示例
以下是一个简单的示例,演示如何使用
dup2
将标准输出重定向到一个文件:在这个示例中,
dup2(fd, STDOUT_FILENO)
将文件描述符fd
(指向output.txt
文件)复制到标准输出(文件描述符1)。因此,printf
函数输出的内容会被写入到output.txt
文件中,而不是标准输出设备(通常是终端)。2.缓冲区
关于缓冲区,其实我要讲的是c语言层面上的缓冲区是语言级别上提供的,而其实os也会提供操作系统内核缓冲区,但是我们这篇文章先不提及
其实printf,fwrite等c语言包装的函数都会提供一个缓冲区(缓冲区也分为全缓冲区和行缓冲区)
就是将即将要输出的内容输入到缓冲区中,当某些特定条件达成的时候才会刷新缓冲区将内容输出
我们使用代码做一个实验:
如果我们直接编译运行这段代码的话就会发现,他的运行结果很符合我们的预期,
但是我们如果重定向这个./buftest > filename
filename这个文件中的话就会发现文件中的内容是这样的
我们发现除了write函数其他的函数都输出了两次这是为什么呢
其实因为fork函数创建了子进程之后,子进程继承了父进程的资源也继承了父进程在c语言层面上的缓冲区,并且语言层面上的缓冲区在对于输出到显示器上是行缓冲但是输出到文件中就是全缓冲了所一输出到显示器上的时候,遇见\n就输出了,就不会存在子进程继承了缓冲区但是缓冲区中还存在内容的情况了
3.文件系统
我们使用ll的时候我们看到的除了文件名还能看见文件元数据:模式(权限mode),硬链接数,文件所有者,所属组,大小,最后修改时间
想要看到更多的信息可以通过stat命令来看到更多信息
关于上面的执行信息:
inode
我们先简单介绍一下文件系统
linux ext2文件系统,上图为磁盘文件系统图。磁盘是典型的块设备,硬盘分区被划分为一个个的block,一个block的大小是有格式化的时候确定的,并且不能更改上图中的boot block(启动快)的大小是确定的
1,Block Group:ext2文件系统会根据分区的大小划分为数个Block Group。而每个Block Group都有着相同的结构组成。政府管理各区的例子
2,超级块(Super Block):存放文件系统本身的结构信息。记录的信息主要有:bolck 和 inode的总量,未使用的block和inode的数量,一个block和inode的大小,最近一次挂载的时间,最近一次写入数据的时间,最近一次检验磁盘的时间等其他文件系统的相关信息。Super Block的信息被破坏,可以说整个文件系统结构就被破坏了
3,GDT,Group Descriptor Table:块组描述符,描述块组属性信息,有兴趣的同学可以在了解一下
4,块位图(Block Bitmap):Block Bitmap中记录着Data Block中哪个数据块已经被占用,哪个数据块没有被占用
5.inode位图(inode Bitmap):每个bit表示一个inode是否空闲可用。
6.i节点表:存放文件属性 如 文件大小,所有者,最近修改时间等
7.数据区:存放文件内容
这样就能间属性和文件内容分开储存了,但是他实际上是怎么操作的呢,我们通过一个touch命令来创建一个新文件来看看是如何工作的
其实inode就相当于每一个文件的身份证
在其中空闲的i节点的编号就是文件的inode值(maybe)
然后相关的那个i节点会存储文件的基本信息
好了,解释到这里,我们再会看一下这个叫硬链接的东西是什么意思
我们看到真正能找到磁盘上文件的不是文件名而是和文件名对应的inode(index node)当我们将多个文件名对应于一个inode上时:我们在使用ll就会发先我们之前创建的abc文件的硬链接数变成了2,这个和inode的链接状态就叫做硬链接,内核记录了这个链接,当我们删除文件时,硬链接就-1,如果硬链接为零,对应的i节点上记录的磁盘空间就释放
还有一种链接叫做软连接相比于硬链接时通过inode来链接软连接就是通过文件名来连接
4.动态库和静态库
- Author:PytC
- URL:https://PytC.fun//article/14549b4c-fd33-80eb-9fed-d2c3e483e7bc
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!