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

这篇具有很好参考价值的文章主要介绍了[Linux]基础IO详解(系统文件I/O接口、文件描述符、理解重定向)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

        hello,大家好,这里是bang___bang_ ,今天和大家谈谈Linux中的基础IO,包含内容有对应的系统文件I/O接口,文件描述符,理解重定向。

[Linux]基础IO详解(系统文件I/O接口、文件描述符、理解重定向),我在地球学Linux,linux,运维,I/O接口,文件描述符,重定向,文件

[Linux]基础IO详解(系统文件I/O接口、文件描述符、理解重定向),我在地球学Linux,linux,运维,I/O接口,文件描述符,重定向,文件  

目录

1️⃣初识文件

2️⃣ 系统文件I/O接口

🍙open

🍙write

🍙read

🍙close

3️⃣文件描述符

🍙0&1&2

🍙内核中文件描述符的探究

🍙分配规则

4️⃣重定向

🍙重定向现象 

🍙重定向的本质

🍙dup2系统调用


1️⃣初识文件

        文件=内容+属性(属性也是数据)

        文件的所有操作:a.对内容    b.对属性

        文件在磁盘(硬件)上放着,我们访问文件,先写代码->编译->exe->运行->访问文件。

        本质上是 进程 在访问文件。

Linux下一切皆文件。曾经我们理解的文件就是磁盘上的那些普通文件能read,write。

        在C语言中,我们对显示器有方法:printf->这是write(output);键盘:scanf->这是read(input)。也就是说我们的显示器和键盘也是文件。

        站在系统的角度来说:我们的程序要加载到内存,键盘相当于把我们的数据输交给内存(input),而内存把读取到的数据刷新到文件或者显示器当中(output)。

系统角度:能够被input读取,或者能够被output写出的设备就叫做文件!

2️⃣ 系统文件I/O接口

        在C语言中,文件操作接口有fopen,fwrite,fprintf,fclose等等,实际上这些接口都是封装了系统I/O接口。[Linux]基础IO详解(系统文件I/O接口、文件描述符、理解重定向),我在地球学Linux,linux,运维,I/O接口,文件描述符,重定向,文件

🍙open

[Linux]基础IO详解(系统文件I/O接口、文件描述符、理解重定向),我在地球学Linux,linux,运维,I/O接口,文件描述符,重定向,文件

pathname: 要打开或创建的目标文件
flags: 打开文件时,可以传入多个参数选项
参数 :
         O_RDONLY: 只读打开
         O_WRONLY: 只写打开
         O_RDWR : 读,写打开
        O_RDONLY  O_WRONLY  O_RDWR 这三个常量,必须指定一个且只能指定一个
         O_CREAT : 若文件不存在,则创建它。需要使用 mode 选项,来指明新文件的访问权限
         O_APPEND: 追加写
        O_TRUNC: 清空文件
mode: 为新建文件设置权限

问题:如何实现flags传入多个参数选项呢?

答:采用位图的思想,flags的参数实际上是一个int类型的数,参数之间进行|运算,就能实现传入多个参数的效果。

[Linux]基础IO详解(系统文件I/O接口、文件描述符、理解重定向),我在地球学Linux,linux,运维,I/O接口,文件描述符,重定向,文件
源码定义

🌰O_WRONLY | O_CREAT 

[Linux]基础IO详解(系统文件I/O接口、文件描述符、理解重定向),我在地球学Linux,linux,运维,I/O接口,文件描述符,重定向,文件
模拟结果

检测是否有当前状态,只需要使用flag&状态的值。

0110 0101 & 0000 0001 = 0000 0001 有O_WRONLY状态

0110 0101 & 0110 0100 = 0110 0100 有O_CREAT状态

open函数图中我框选了返回值为一个文件描述符,在下面讲解。

🌰简单使用open

#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<assert.h>

int main()
{
    int fd=open("log.txt",O_WRONLY | O_CREAT,0666);
    assert(fd!=-1);
    printf("open sucess! fd:%d\n",fd);
    return 0;    
}
[Linux]基础IO详解(系统文件I/O接口、文件描述符、理解重定向),我在地球学Linux,linux,运维,I/O接口,文件描述符,重定向,文件
权限解释

🍙write

[Linux]基础IO详解(系统文件I/O接口、文件描述符、理解重定向),我在地球学Linux,linux,运维,I/O接口,文件描述符,重定向,文件

[Linux]基础IO详解(系统文件I/O接口、文件描述符、理解重定向),我在地球学Linux,linux,运维,I/O接口,文件描述符,重定向,文件

 功能:把缓冲区buf的前count字节写入与文件描述符fd关联的文件中。它返回实际写入的字节数。

🌰测试write

#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<assert.h>
#include<string.h>
int main()
{
    int fd=open("log.txt",O_WRONLY | O_CREAT | O_TRUNC,0666);
    assert(fd!=-1);
    printf("open sucess! fd:%d\n",fd);
    const char* buf="This is a test\n";
    write(fd,buf,strlen(buf));
    return 0;    
}

[Linux]基础IO详解(系统文件I/O接口、文件描述符、理解重定向),我在地球学Linux,linux,运维,I/O接口,文件描述符,重定向,文件

🍙read

[Linux]基础IO详解(系统文件I/O接口、文件描述符、理解重定向),我在地球学Linux,linux,运维,I/O接口,文件描述符,重定向,文件

功能:从与文件描述符fd相关联的文件中读取count个字节的数据。并把它放入到数据区buf中。

🌰测试read,读取上面write写的内容

int main()
{
    int fd=open("log.txt",O_RDONLY);
    assert(fd!=-1);
    printf("open sucess! fd:%d\n",fd);

    char res[64];
    read(fd,res,sizeof(res));
    printf("res:%s",res);
    return 0;    
}

[Linux]基础IO详解(系统文件I/O接口、文件描述符、理解重定向),我在地球学Linux,linux,运维,I/O接口,文件描述符,重定向,文件

🍙close

[Linux]基础IO详解(系统文件I/O接口、文件描述符、理解重定向),我在地球学Linux,linux,运维,I/O接口,文件描述符,重定向,文件 

功能:将文件描述符fd相关联的文件关闭。

🌰close操作演示

int main()
{
    int fd=open("log.txt",O_RDONLY);
    assert(fd!=-1);
    printf("open sucess! fd:%d\n",fd);
    close(fd);
    return 0;    
}

3️⃣文件描述符

🍙0&1&2

🌰fd的显示问题:

int main()
{
    int fd1=open("log1.txt",O_WRONLY | O_CREAT | O_TRUNC,0666);
    int fd2=open("log2.txt",O_WRONLY | O_CREAT | O_TRUNC,0666);
    int fd3=open("log3.txt",O_WRONLY | O_CREAT | O_TRUNC,0666);
    int fd4=open("log4.txt",O_WRONLY | O_CREAT | O_TRUNC,0666);
    assert(fd1!=-1);
    assert(fd2!=-1);
    assert(fd3!=-1);
    assert(fd4!=-1);
    printf("open sucess! fd1:%d\n",fd1);
    printf("open sucess! fd2:%d\n",fd2);
    printf("open sucess! fd3:%d\n",fd3);
    printf("open sucess! fd4:%d\n",fd4);
    close(fd1);
    close(fd2);
    close(fd3);
    close(fd4);
    return 0;    
}

问题:为什么fd是从3开始? 

[Linux]基础IO详解(系统文件I/O接口、文件描述符、理解重定向),我在地球学Linux,linux,运维,I/O接口,文件描述符,重定向,文件

答:实际上C/C++程序默认会打开三个文件流:标准输入stdin(0),标准输出stdout(1),标准错误stderr(2)

0,1,2一般对应的物理设备是:键盘,显示器,显示器。

🍙内核中文件描述符的探究

在上面我们可以发现文件描述符fd就是一个小整数,那么在内核中文件描述符究竟是什么呢?

[Linux]基础IO详解(系统文件I/O接口、文件描述符、理解重定向),我在地球学Linux,linux,运维,I/O接口,文件描述符,重定向,文件
内核结构
        当我们打开文件时,操作系统在内存中要创建相应的数据结构来描述目标文件。于是就有了file结构体。表示一个已经打开的文件对象。而进程执行 open 系统调用,所以必须让进程和文件关联起来。每个进程都有一个指针*files, 指向一张表 files_struct, 该表最重要的部分就是包涵一个指针数组,每个元素都是一个指向打开文件的指针!所以,本质上, 文件描述符就是该数组的下标 。所以,只要拿着文件描述符,就可以找到对应的文件。
[Linux]基础IO详解(系统文件I/O接口、文件描述符、理解重定向),我在地球学Linux,linux,运维,I/O接口,文件描述符,重定向,文件
抽象结构图

🍙分配规则

在files_struct数组当中,找到当前没有被使用的最小的一个下标,作为新的文件描述符。

🌰验证分配规则,关闭文件0,进行分配。

int main()
{
    close(0);
    int fd=open("log1.txt",O_WRONLY | O_CREAT | O_TRUNC,0666);
    assert(fd!=-1);
    printf("open sucess! fd:%d\n",fd);
    close(fd);

    return 0;    
}

[Linux]基础IO详解(系统文件I/O接口、文件描述符、理解重定向),我在地球学Linux,linux,运维,I/O接口,文件描述符,重定向,文件

问题:如果关闭文件描述符1,为什么没有输出显示。

[Linux]基础IO详解(系统文件I/O接口、文件描述符、理解重定向),我在地球学Linux,linux,运维,I/O接口,文件描述符,重定向,文件

答:文件描述符1对应显示器,关闭后自然就不会有内容显示到显示器了,但是也没有显示到文件log.txt中。

4️⃣重定向

🍙重定向现象 

问题:上面例子中内容没有显示到显示器和文件log.txt中,那么内容实际上在哪个地方?

答:在文件的缓冲区中

那是不是意味着我们刷新缓冲区就可以将内容显示出来?

int main()
{
    close(1);
    int fd=open("log.txt",O_WRONLY | O_CREAT| O_TRUNC,0666);
    assert(fd!=-1);
    printf("open sucess! fd:%d\n",fd);
    fflush(stdout);//刷新缓冲区
    close(fd);
    return 0;    
}

[Linux]基础IO详解(系统文件I/O接口、文件描述符、理解重定向),我在地球学Linux,linux,运维,I/O接口,文件描述符,重定向,文件

刷新后成功输出,内容本来应该输出到显示屏,但是现在输出到了log.txt这实际上就是输出重定向!!!(O_CREAT创建文件,O_TRUNC刷新文件,实现C语言中的w模式;O_APPEND追加内容,实现C语言中的a模式)

🍙重定向的本质

重定向的本质,其实是在OS内部,更改fd对应的内容的指向!!

[Linux]基础IO详解(系统文件I/O接口、文件描述符、理解重定向),我在地球学Linux,linux,运维,I/O接口,文件描述符,重定向,文件

🍙dup2系统调用

在重定向中,我们通常不使用close关闭fd,再重定向,而是直接使用系统调用dup2来重定向。 

[Linux]基础IO详解(系统文件I/O接口、文件描述符、理解重定向),我在地球学Linux,linux,运维,I/O接口,文件描述符,重定向,文件

将oldfd的内容给newfd,即newfd对应内容指向oldfd

🌰dup2系统调用测试

#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<assert.h>
#include<unistd.h>

int main()
{
    int fd=open("log.txt",O_WRONLY | O_CREAT| O_TRUNC,0666);
    assert(fd!=-1);
    dup2(fd,1);
    printf("open sucess! fd:%d\n",fd);
    close(fd);
    return 0;    
}
[Linux]基础IO详解(系统文件I/O接口、文件描述符、理解重定向),我在地球学Linux,linux,运维,I/O接口,文件描述符,重定向,文件
dup2实现重定向

文末结语,本文讲解Linux的基础IO,包含内容:初识文件,系统文件I/O接口open、read、write、close,文件描述符的详细讲解以及文件描述符的分配规则,重定向现象的演示及重定向的本质讲解,实现重定向的系统调用dup2。如有需要,希望能有所帮助!!!文章来源地址https://www.toymoban.com/news/detail-662569.html

到了这里,关于[Linux]基础IO详解(系统文件I/O接口、文件描述符、理解重定向)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 【Linux】基础IO_文件描述符与重定向

    环境:centos7.6,腾讯云服务器 Linux文章都放在了专栏:【 Linux 】欢迎支持订阅 相关文章推荐: 【Linux】冯.诺依曼体系结构与操作系统 【C/进阶】如何对文件进行读写(含二进制)操作? 【Linux】基础IO_文件操作 在前文中学习了open函数,我们知道 open函数的返回值就是文件描

    2024年02月03日
    浏览(73)
  • 【Linux】基础 IO(文件系统 & inode & 软硬链接)-- 详解

    1、前言 我们一直都在说打开的文件,磁盘中包含了上百万个文件,肯定不可能都是以打开的方式存在。其实文件包含打开的文件和普通的未打开的文件,下面重点谈谈未打开的文件。 我们知道打开的文件是通过操作系统被进程打开,一旦打开,操作系统就要维护多个文件,

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

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

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

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

    2024年02月08日
    浏览(51)
  • Linux基础IO【文件理解与操作】

    ✨个人主页: Yohifo 🎉所属专栏: Linux学习之旅 🎊每篇一句: 图片来源 🎃操作环境: CentOS 7.6 阿里云远程服务器 Great minds discuss ideas. Average minds discuss events. Small minds discuss people. 大智论道,中智论事,小智论人。 文件操作是 基础IO 学习的第一步,我们在 C语言 进阶中,就

    2024年02月02日
    浏览(43)
  • Linux 文件:IO接口详解及实操

    在c语言文件中,创建、打开、读、写操作可以通过如下的代码进行: 通过\\\'w\\\'指令对文件进行写入操作时,编译器会先将文件内容清空然后重新写入。 C默认会打开三个输入输出流,分别是stdin, stdout, stderr。 仔细观察发现,这三个流的类型都是FILE*, fopen返回值类型,文件指针

    2024年01月24日
    浏览(35)
  • 【创作赢红包】| 【Linux】 基础IO——自己实现文件接口FILE

    模仿C库,自己封装一个最简单的文件接口 FILE 创建makefile 创建MY_FILE结构体 内部包含文件描述符fd,输出缓冲区ou’tputbuffer 、flags刷新方法 分别通过C库中fopen 、fwrite、fclose 接口的实现,设计属于自己的接口 1. MY_fopen的实现 1.识别标志位 分别实现了读、写追加方式 2. 尝试打开

    2024年02月02日
    浏览(44)
  • 【Linux】基础IO——文件系统

    磁盘计算机上唯一的一个机械设备,同时它还是外设 机械磁盘很便宜,虽然效率会慢一些,所以企业一般使用机械磁盘,因为便宜 磁盘不仅仅外设,还是一个机械设备(盘片、磁头),所以磁盘一定非常慢 盘片:一片两面,有一摞盘片 磁头:一面一个磁头 一个磁头负责一面的

    2023年04月09日
    浏览(46)
  • 【Linux】基础IO_文件系统

     环境:centos7.6,腾讯云服务器 Linux文章都放在了专栏:【 Linux 】欢迎支持订阅 相关文章推荐: 【Linux】冯.诺依曼体系结构与操作系统 【C/进阶】如何对文件进行读写(含二进制)操作? 【Linux】基础IO_文件操作 【Linux】基础IO_文件描述符与重定向 在前文我们所讲的都是

    2024年02月05日
    浏览(42)
  • 【Linux】基础IO——系统文件IO&&fd&&重定向

    大家好我是沐曦希💕 空文件,也要在磁盘占据空间,因为文件也有属性,属性也属于数据,需要空间进行存储。所以 文件包括内容和属性 所以 对文件操作就是对内容或者对属性进行操作,或者对内容和属性进行操作。 文件具有唯一性,所以在 标定一个文件时候,必须使用

    2024年02月02日
    浏览(46)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包