Linux基础IO-1.0——open、close、read及write-深入手搓分析!

@bit::Shadow
✧(≖ ◡ ≖✿

目录

理解文件

狭义:

Linux下一切皆文件

操作系统

文件操作

open与close

函数原型:

参数:

为什么不是"&&"呢?

返回值

close

只读RDONLY

写相关

执行结果:

write与read

返回值

read()

write()

fd再分析

fd前三者

内核区fd

文件描述符fd的分配原则:

[*重定向 > 与追加重定向 >>](#*重定向 > 与追加重定向 >>)

*语言的可移植性


理解文件

鲁迅曾说:"Linux下一切皆文件"。

狭义:

  • 文件存储在磁盘里。
  • 磁盘是永久性存储介质,因此文件的属性+内容是永久性的,不随关机而数据消失。
  • 磁盘是外设,既是输入设备 又是输出设备
  • 对磁盘所有的操作均是对外设的输入输出,简称IO。

Linux下一切皆文件

计算机组成原理:

从下至上分别是:硬件 驱动 操作系统(进程管理

文件管理、内存管理、驱动管理等等) 库、系统调用 语言层

操作系统

操作系统统一管理软硬件,即操作系统才是磁盘真正的管理者->系统调用接口访问文件。

计算机启动默认打开的三个文件流:标准输出流,标准输入流及标准错误流。

  • extern FILE* stdin; // 标准输入流 cin;
  • extern FILE* stdout; // 标准输出流 c++中 cout;
  • extern FILE* stderr; // 标准错误流 cerr;

计算机内文件的组织模式:结构体+链表

文件操作

open与close

功能:open and possibly creat a file or device。

函数原型:

cpp 复制代码
int open(const char* pathname, int flags);
int open(const char* pathname, int flags, mode_t mode);

参数:

pathname:文件路径

flags:访问模式+行为标志

☆☆flags常用选项:

|-----------|-----------------------------|
| O_RDONLY | 只读 |
| O_WRONLY | 只写 | 不存在无时自动创建 |
| O_CREAT | 文件不存在则创建 |
| O_APPNED | 追加写入模式 |
| ☆☆O_TRUNC | 如果文件存在清空内容 truncate(截断) |

☆☆mode:创建文件时的权限。 仅当选项存在O_CREAT 时,必定添加的参数否则权限混乱

多mode间加 | 链接。

为什么不是"&&"呢?

  • O_WRONLYO_CREATO_APPEND整数常量(通常是 2 的幂次方:1、2、4、8...)

  • | 将它们按位或计算组合成一个单一的整数标志值

  • && 返回的是逻辑真值(0 或 1),完全不是预期的标志组合

返回值

作为文件标识id,常用fd为fileID的缩写。

close

关闭开启的文件,防止资源泄露。

int close(int fd);

关闭失败返回-1;

只读RDONLY

cpp 复制代码
void testRDONLY() //以只读方式打开
{
    int fd = open("txt.txt", O_RDONLY);
    if(fd == -1) 
    {
        perror("open failed!!\n");
        exit(-1);
    }
    char buffer[10];
    //............read()的使用
    close(fd);
}

写相关

cpp 复制代码
void test3() //以写相关方式打开
{
    int fd1 = open("test1.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);//每次打开均清空
    int fd2 = open("test2.txt", O_WRONLY | O_CREAT | O_APPEND, 0666);//每次打开不清空而追加

    if(!(fd1 != -1 && fd2 != -1))
    {
        perror("open failed!!\n");
        exit(-1);
    }
    char buffer[129];
    //............
    close(fd1);
    close(fd2);
}

执行结果:

普通用户默认创建文件的的权限值是0666,与umask 0002相减得权限值0664因此得以下结果:

write与read

作用对象是fd对应的文件。read指读取fd内count个字节数据到指针数组buff内,write指写buf内的count个字节数据到fd内。

cpp 复制代码
#include<cunistd>

ssize_t read(int fd, void* buff, size_t count);
ssize_t write(int fd, const void* buf, size_t count);

返回值

read()

|--------|-------------|-----------------|
| read() |||
| 返回值 | 含义 | 处理方式 |
| >0 | 成功读到数据 | 正常处理,可能小于count |
| =0 | 到达文件末尾(EOF) | 表示无更多数据,关闭或结束循环 |
| -1 | 发生错误 | 检查errno |

write()

返回值代表成功写入fd内的字节数据个数。

|---------------|--------|---------|
| write() |||
| 返回值 | 含义 | 处理方式 |
| =count | 全部写入成功 | 正常完成 |
| 0<ret<count | 部分写入成功 | 写入 |
| =0 | 没有写入任何 | |
| -1 | 发生错误 | 检查errno |

fd再分析

fd作为open的返回值,是文件打开的标识符,通过使用fd链接对象文件进行各种各样的操作。

cpp 复制代码
void test3() //以写相关方式打开
{
    int fd1 = open("test1.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);//每次打开均清空
    int fd2 = open("test2.txt", O_WRONLY | O_CREAT | O_APPEND, 0666);//每次打开不清空而追加
    int fd3 = open("test3.txt", O_WRONLY | O_CREAT | O_APPEND, 0666);//每次打开不清空而追加

    if(!(fd1 != -1 && fd2 != -1 && fd3 != -1))
    {
        perror("open failed!!\n");
        exit(-1);
    }
    printf("fd1=%d,fd2=%d,fd3=%d\n",fd1,fd2,fd3); 
    close(fd1);
    close(fd2);
    close(fd3);
}

运行发现:

即3 4 5分别作为文件的标识符。

本次学习文件gitee选看

fd前三者

在最初标识符3前其实还有0 1 2分别对应默认打开的三个文件,标准输入、标准输出及标准错误。

|----|--------|----|------|
| fd | 符号 | 设备 | 用途 |
| 0 | stdin | 键盘 | 标准输入 |
| 1 | stdout | 屏幕 | 标准输出 |
| 2 | stderr | 屏幕 | 标准错误 |

内核区fd

0->标准输入文件

1->标准输出文件

2->标准错误

文件描述符fd的分配原则:

从先前的3 4 5就可以看出:fd总是从下标0找到第一个非未分配下标作为该文件的fd,因此若我们close(1),就相当于将对应下标为1处的文件(对应标准输出)关闭。若此时再新开一个文件,此文件fd就会重定向到下标为1的位置。

*重定向 > 与追加重定向 >>

重定向 " > " 与 " w "的打开模式相对应:

清空文件内容并写入

bash 复制代码
echo abc > log.txt

追加重定向 ">>" 与O_APPEND对应:

原:

echo abc >> txt.txt

后:

在追加对象的下一行添加内容

bash 复制代码
echo def >> log.txt

*语言的可移植性

例:C语言的各种库基于不同平台内部已经实现了封装。使得一门语言在不同平台下形成相同的效果。

感谢观看

求关注

相关推荐
十月的皮皮20 小时前
C语言学习笔记20260612-菱形图案打印(两种写法)
c语言·笔记·学习
MXsoft61820 小时前
**智慧校园哑终端监控:摄像头、门禁、信息屏的统一管理实践**
运维
天天进步201520 小时前
Tunnelto 源码解析 #13:自托管部署:Docker、环境变量、端口规划与单实例限制
开发语言
AI科技星20 小时前
第三卷:质数王朝志(全卷定稿)
c语言·开发语言·汇编·electron·概率论
dadaobusi20 小时前
Linux内核完成大量内存/调度/时间子系统初始化的关键阶段
java·linux·前端
唐墨12320 小时前
关于linux kernel错误码为负数编码这件事情,我个人的一些看法
linux·运维·服务器
chase。20 小时前
【学习笔记】RIGVid:通过模仿生成视频实现机器人操作,无需物理演示
笔记·学习·音视频
Full Stack Developme20 小时前
Linux Shell 教程概览
linux·前端·chrome
kyle~20 小时前
DDS分布式实时系统---自省机制
开发语言·分布式·机器人·c#·接口·ros2
yujunl20 小时前
Integrated Security=True(Windows 集成身份验证)
开发语言