@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。

函数原型:

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

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分别作为文件的标识符。

本次学习文件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 ”的打开模式相对应:

清空文件内容并写入

echo abc > log.txt

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

原:

echo abc >> txt.txt

后:

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

echo def >> log.txt

*语言的可移植性

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

感谢观看
求关注

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐