【Linux】文件描述符与重定向操作

这篇具有很好参考价值的文章主要介绍了【Linux】文件描述符与重定向操作。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

系列文章

收录于【Linux】文件系统 专栏

对于Linux下文件的写入与读取,以及文件原理还有疑惑的可以看看上一篇文章浅谈文件原理与操作。


目录

系列文章

再谈文件描述符

IO函数的本质

一切皆文件

文件重定向

原理

系统接口


再谈文件描述符

🍧上一篇文章中,我们就提到了 open 的返回值即 fd,又称为文件描述符,之后我们进行读写操作时就需要用到 fd。

🍧而 fd 究竟是什么来头,下面我们来一起揭秘。

【Linux】文件描述符与重定向操作

🍧我们首先先打开一个文件,再打印返回的 fd ,观察一下输出的结果。

#define myfile "log.txt"

int main()
{
    int fd = open(myfile, O_WRONLY | O_CREAT | O_TRUNC, 0666);
    cout << fd << endl;
    return 0;
}

【Linux】文件描述符与重定向操作

🍧输出的是 3,这个 3 有什么特殊的含义吗?是意味着文件是打开的第三个文件吗?

🍧其实,任何一个进程在启动的时候,默认会打开当前进程的三个文件

标准输入 标准输出 标准错误
C语言 stdin stdout stderr
CPP cin cout cerr
文件类型 键盘文件 显示器文件 显示器文件
fd 0 1 2

🍧因为一开始打开了三个文件,从而我们第一次打开文件时 fd 便从 3 开始了!讲到这里,你应该能大概猜到 fd 是什么了吧。

🍧没错,就是数组下标

🍧之前我们讲过,文件是用户通过调用进程打开的,于是在内存之中就会存在一个个包含文件大部分属性的 struct file。当我们找到 struct file 时就意味着我们找到了被打开的文件,而用户能访问到的只有进程的 task_struct。

🍧因此,系统需要将该进程打开的文件管理起来,就有了 file_struct,其中的 fd_array 就负责存储 struct file 的指针。最后 tack_struct 再使用指针与 file_struct 关联起来即可。其中fd就是 fd_array 数组的下标。

【Linux】文件描述符与重定向操作

🍧因此,只要知道 fd 就能在 fd_arry 中的位置就能找到对应 struct file 的指针,进而找到 struct file。

🍧这样的结构设计同时还实现了进程管理与文件系统解耦合,只用指针进行轻度的连接。

IO函数的本质

🍧不仅如此,每一个 struct file 都有属于自己的缓冲区,本质上我们调用 wirte 函数就是将数据拷贝到这个缓冲区之中,至于什么时候刷新到磁盘中的指定位置,则有 OS 自主决定。

🍧而 read 前便会将磁盘的数据拷贝到缓冲区里,之后找到缓冲区读取数据。

【Linux】文件描述符与重定向操作

即 IO 函数的本质就是拷贝函数,在用户空间和内核空间之间来回拷贝。

一切皆文件

🍧我们常说:“Linux 下一切皆文件。” 这句话又该如何理解呢?而其中最困扰我们的就是如何将外设也看成文件。

🍧由于每种外设读取与写入的方式都不相同,因此需要安装特定的驱动程序才能使用。

【Linux】文件描述符与重定向操作

🍧而有些外设只读不写或是只写不读就没有对应的驱动程序。 

🍧这时候我们再回过头来看struct file这个结构。

struct file
{
    //文件权限
    //文件大小
    //缓冲区
    ...
    int (*readp)(int fd,char* buffer,int size);
    int (*writep)(int fd,char* buffer,int size);
};

🍧其中两个函数指针则分别指向了驱动程序的读写函数。 

🍧即:操作系统的文件操作只是将数据拷贝到文件的缓冲区中,之后再调用目标文件的自身的读写操作,完成读写。 

🍧每个设备都可以将其驱动程序填入文件的结构体,因此在进程看来外设也是文件。同时,我们在访问 OS 时都是通过进程代为执行,而进程认为一切皆 struct file 但其中究竟是设备还是文件,进程不知道也不关心。由此在用户看来最终就是一切皆文件的现象。

文件重定向

🍧之前我们就在命令行使用过文件重定向的操作,将原本要输出到显示器的信息重定向到文件之中

echo hello log.txt > log.txt   //将语句写入到log.txt文件中

这种操作是如何用代码的实现的呢?下面一起来看看吧。

原理

🍧首先,我们得先了解一下文件描述符的分配规则: 选文件描述表中最小的、没有被使用的数组元素,分配给新文件

🍧我们可以用一段代码来验证一下。

int main()
{
    int fd1 = open("log.txt",O_WRONLY | O_CREAT | O_TRUNC, 0666);
    cout<<fd1<<endl;
    close(fd1);
    int fd2 = open("out.txt",O_WRONLY | O_CREAT | O_TRUNC, 0666);
    cout<<fd2<<endl;
    close(fd2);
    return 0;
}

【Linux】文件描述符与重定向操作

🍧可以看到,两次 fd 都是 3,这是因为一开始的 fd 就是从 3 开始的,打印 fd 后关闭文件再打开一个新文件时,文件描述表中还是只有三个文件,于是 fd 还是从 3 开始分配。

🍧这时候,我们便想:前面三个文件能不能关闭呢?我们再次打开文件会发生什么事呢?

#define myfile "log.txt"

int main()
{
    close(0);
    int fd = open(myfile, O_WRONLY | O_CREAT | O_TRUNC, 0666);
    cout << fd << endl;
    return 0;
}

【Linux】文件描述符与重定向操作 

🍧很明显,新文件的 fd 便是刚才关闭的 0。若我们关闭1号标准输出文件,然后再调用 printf 或 cout 输出流进行输出呢?

🍧这次程序运行完我们却没有看到显示器有进行输出,我们查看 log.txt 这个文件便会发现,信息被输出到了文件之中。

【Linux】文件描述符与重定向操作

🍧从操作系统的角度出发,OS 只知道标准输出的 fd 是 1,当遇到需要输出的情况时就找到 fd 对应的文件进行输出。因此,OS 并不知道此时 1 已经不是对应着标准输出这件事,便直接向文件写入。

🍧即重定向的原理便是:在上层不知道的情况下,在OS内部更改进程对应的文件描述符表中特定下标的指向

系统接口

🍧若是每次要重定向时都要像上面那样先关闭文件,再打开一个新文件匹配 fd 未免有些麻烦。

🍧OS内部有一个函数便可实现重定向的功能。

【Linux】文件描述符与重定向操作

【Linux】文件描述符与重定向操作

🍧我们使用 dup2 便可以直接实现函数的重定向,第一个参数原来的 fd第二个参数则是想要关闭文件的 fd

int main()
{
    int fd = open(myfile, O_WRONLY | O_CREAT | O_TRUNC, 0666);
    dup2(fd, 1);
    printf("hello this is stdout\n");
    close(fd);
    return 0;
}

 🍧借助这个功能,我们可以简单的对运行结果进行一个记录,输出和错误分别记录在不同的文件中。

int main()
{
    int fd1 = open("out.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);
    int fd2 = open("error.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);
    dup2(fd1,1);
    dup2(fd2,2);
    cout << "hello cout" << endl;
    cerr << "hello cerr" << endl;
    close(fd1);
    close(fd2);
    return 0;
}

【Linux】文件描述符与重定向操作


🍧好了,今天 文件描述符与重定向操作 的相关内容到这里就结束了,如果这篇文章对你有用的话还请留下你的三连加关注。文章来源地址https://www.toymoban.com/news/detail-485427.html

到了这里,关于【Linux】文件描述符与重定向操作的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 【Linux】基础IO(一) :文件描述符,文件流指针,重定向

    【Linux】基础IO(一) :文件描述符,文件流指针,重定向

    🍎 作者: 阿润菜菜 📖 专栏: Linux系统编程 是不是只有C/C++有文件操作呢?python、java、go等文件接口操作的方法是不太一样的,那如何理解这种现象?有没有统一的视角去看待所有的语言文件操作呢?—我们今天从系统视角去理解 ---- 实际都是通过系统调用来访问 文件=内

    2024年01月18日
    浏览(11)
  • 『Linux』文件描述符及重定向——为何说Linux下,一切皆文件?

    『Linux』文件描述符及重定向——为何说Linux下,一切皆文件?

    🌸作者简介: 花想云 ,在读本科生一枚,C/C++领域新星创作者,新星计划导师,阿里云专家博主,CSDN内容合伙人…致力于 C/C++、Linux 学习。 🌸 专栏简介:本文收录于 Linux从入门到精通 ,本专栏主要内容为本专栏主要内容为Linux的系统性学习,专为小白打造的文章专栏。

    2024年02月12日
    浏览(11)
  • Linux学习之系统默认打开的文件描述符、重定向

    Linux学习之系统默认打开的文件描述符、重定向

    一个进程默认会打开标准输入、标准输出、错误输出三个文件描述符。可以在 /proc/PID/fd 里边可以看到打开文件的描述符,PID需要改成具体的 pid ,比如可以使用 A终端 输入 vim proctest 之后按下回车键。 打开一个vim编辑窗口。 再打开一个 B终端 ,输入 ps -aux | grep \\\'vim\\\' 查找一下

    2024年02月13日
    浏览(9)
  • 【Linux】基础IO----系统文件IO & 文件描述符fd & 重定向

    【Linux】基础IO----系统文件IO & 文件描述符fd & 重定向

    作者:დ旧言~ 座右铭:松树千年终是朽,槿花一日自为荣。 目标:了解在Linux下的系统文件IO,知道什么是文件描述符,什么是重定向 毒鸡汤:白日莫闲过,青春不再来。 专栏选自:Linux初阶 望小伙伴们点赞👍收藏✨加关注哟💕💕 最早我们在C语言中学习关于如何用代码

    2024年04月14日
    浏览(7)
  • 【Linux】Linux的管道与重定向

    【Linux】Linux的管道与重定向

    🍎 个人博客: 个人主页 🏆 个人专栏: Linux ⛳️   功不唐捐,玉汝于成 目录 前言 正文 管道(Pipe): 语法: 工作原理: 示例: 重定向(Redirection): 输入重定向: 输出重定向: 示例: 组合使用: 结语  我的其他博客 在Linux系统中,管道和重定向是使命令行操作更为

    2024年03月20日
    浏览(9)
  • [Linux]基础IO详解(系统文件I/O接口、文件描述符、理解重定向)

    [Linux]基础IO详解(系统文件I/O接口、文件描述符、理解重定向)

            hello,大家好,这里是bang___bang_ ,今天和大家谈谈Linux中的基础IO,包含内容有对应的系统文件I/O接口,文件描述符,理解重定向。    目录 1️⃣初识文件 2️⃣ 系统文件I/O接口 🍙open 🍙write 🍙read 🍙close 3️⃣文件描述符 🍙012 🍙内核中文件描述符的探究 🍙分配

    2024年02月12日
    浏览(8)
  • 『Linux从入门到精通』第 ⑲ 期 - 文件描述符及重定向——为何说Linux下,一切皆文件?

    『Linux从入门到精通』第 ⑲ 期 - 文件描述符及重定向——为何说Linux下,一切皆文件?

    🌸作者简介: 花想云 ,在读本科生一枚,C/C++领域新星创作者,新星计划导师,阿里云专家博主,CSDN内容合伙人…致力于 C/C++、Linux 学习。 🌸 专栏简介:本文收录于 Linux从入门到精通 ,本专栏主要内容为本专栏主要内容为Linux的系统性学习,专为小白打造的文章专栏。

    2024年02月16日
    浏览(11)
  • 【探索Linux】—— 强大的命令行工具 P.12(文件描述符 | 重定向 | 基础IO)

    【探索Linux】—— 强大的命令行工具 P.12(文件描述符 | 重定向 | 基础IO)

    前面我们讲了C语言的基础知识,也了解了一些数据结构,并且讲了有关C++的一些知识,也学习了一些Linux的基本操作,也了解并学习了有关Linux开发工具vim 、gcc/g++ 使用、yum工具以及git 命令行提交代码也相信大家都掌握的不错,上一篇文章我们了解了基础IO,文件操作,今天

    2024年02月08日
    浏览(13)
  • 【探索Linux】文件描述符 | 重定向 | 基础IO —— 强大的命令行工具 P.12

    【探索Linux】文件描述符 | 重定向 | 基础IO —— 强大的命令行工具 P.12

    前面我们讲了C语言的基础知识,也了解了一些数据结构,并且讲了有关C++的一些知识,也学习了一些Linux的基本操作,也了解并学习了有关Linux开发工具vim 、gcc/g++ 使用、yum工具以及git 命令行提交代码也相信大家都掌握的不错,上一篇文章我们了解了基础IO,文件操作,今天

    2024年02月08日
    浏览(12)
  • 【看表情包学Linux】文件描述符 | 重定向 Redirection | dup2 函数 | 缓冲区的理解 (Cache)

    【看表情包学Linux】文件描述符 | 重定向 Redirection | dup2 函数 | 缓冲区的理解 (Cache)

       🤣  爆笑 教程  👉 《看表情包学Linux》👈   猛戳订阅     🔥 💭 写在前面: 在上一章中,我们已经把 fd 的基本原理搞清楚了。本章我们将开始探索 fd 的应用特征,探索 文件描述符的分配原则。讲解重定向,上一章是如何使用 fflush 把内容变出来的,介绍 dup2 函数,

    2023年04月25日
    浏览(10)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包