Linux基础IO-1.0——open、close、read及write-深入手搓分析!
本文摘要:文章探讨了Linux系统中"一切皆文件"的概念,重点分析了文件操作原理。内容包括:1)文件存储机制,磁盘作为永久存储介质;2)操作系统通过系统调用管理文件;3)标准输入/输出/错误流及其文件描述符(0/1/2);4)文件打开模式(O_RDONLY/O_WRONLY等)和权限设置;5)read/write函数的使用方法;6)文件描述符分配原则和重定向机制。文章通过代码示
✧(≖ ◡ ≖✿
目录
理解文件
鲁迅曾说:“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。
函数原型:
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_WRONLY、O_CREAT、O_APPEND是整数常量(通常是 2 的幂次方:1、2、4、8...) -
|将它们按位或计算组合成一个单一的整数标志值 -
&&返回的是逻辑真值(0 或 1),完全不是预期的标志组合
返回值
作为文件标识id,常用fd为fileID的缩写。
close
关闭开启的文件,防止资源泄露。
int close(int fd);
关闭失败返回-1;
只读RDONLY
void testRDONLY() //以只读方式打开
{
int fd = open("txt.txt", O_RDONLY);
if(fd == -1)
{
perror("open failed!!\n");
exit(-1);
}
char buffer[10];
//…………read()的使用
close(fd);
}
写相关
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内。
#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链接对象文件进行各种各样的操作。
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分别作为文件的标识符。
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 ”的打开模式相对应:
清空文件内容并写入
echo abc > log.txt
追加重定向 ">>" 与O_APPEND对应:
原:

echo abc >> txt.txt
后:

在追加对象的下一行添加内容
echo def >> log.txt
*语言的可移植性
例:C语言的各种库基于不同平台内部已经实现了封装。使得一门语言在不同平台下形成相同的效果。
感谢观看
求关注
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐

所有评论(0)