Linux---基础IO详解

一、理解文件

1、1-1、狭义理解

在侠义上,文件就是存储在磁盘等介质上的数据集合,比如.txt、.c、.jpg。等

特点是:有文件名、有大小、有内容、是我们最直观接触到的文件形式。

2、1-2、广义理解:

Linux的核心思想是:Linux下一切皆文件,在Linux系统中,几乎所有的资源都被抽象成文件。

包括:普通文件、目录、设备(键盘、显示器、磁盘、网卡)、管道、套接字(socket)等

好处:

统一了操作接口,对设备的读写就像对普通文件的读写一样。

文件=文件的内容+文件的属性(元数据)

1-3、文件操作的归类认知

1、打开(open):建立进程与文件的链接,获取操作句柄。

2、读写(read/weite):从文件中读取数据,或向文件写入数据。

3、定位(seek):移动文件内部的读写位置指针。

4、关闭(close):断开进程与文件的连接,释放资源。

1-4、系统角度

从操作系统视角看,文件是一个被管理的对象,有对应的元数据(如:权限、大小、创建时间)

进程通过文件描述符(File Descriptor)来引用和操作这些文件对象。

Fopen

访问为文件之前,必须先打开文件,用fopen,用完再用close,动态的打开,文件是一个动态被打开的过程(程序跑起来之后,临时做的fopen就是典型的动态打开),不是编译时打开,而是运行时才打开。

打开文件就是进程在打开文件,因为是动态打开的,程序跑起来,就是进程;所以是进程打开文件的,研究文件和程序的关系,本质是研究进程和文件的关系。

路径

访问任何文件,必须要有路径要么用户自己提供要么用户使用进程的cwd

二、回顾c文件接口

2-1 、输出信息到显示器的方法

1、printf();格式化输出到标准输出(stdout)

2、puts():输出字符串并自动换行

3、putchar():输出单个字符

4、fprintf(stdout,...):等价于printf(),显式指定输出到stdout

5、write(1,...):使用系统调用直接向文件描述符(stdout)写入。

2-2、stdin 、 stdout、 stderr

1、标准输入(stdin):文件描述符为0,默认是键盘、用于读取数据

2、标准输出(stdout):文件描述符是1,默认是显示器,用于输出正常信息

3、标准错误(stderr):文件描述符为2,默认是显示器,用于输出错误信息

在c语言中,他们是三个预定义的FILE* 指针:stdin、stdout、stderr

重定向的本质就是改变着三个流的指向。例如:command> output.txt就是将stdout重定向到文件。

|----|-----|--------|-------|------|------------|
| 模式 | 含义 | 文件不存在时 | 文件存在时 | 初始位置 | 读写限制 |
| r | 只读 | 报错 | 打开 | 文件开头 | 只能读 |
| r+ | 读写 | 报错 | 打开 | 文件开头 | 可读可写 |
| w | 只写 | 创建新文件 | 清空内容 | 文件开头 | 只能写 |
| w+ | 读写 | 创建新文件 | 清空内容 | 文件开头 | 可读可写 |
| a | 追加 | 创建新文件 | 打开 | 文件末尾 | 只能写且只能追加 |
| a+ | 读追加 | 创建新文件 | 打开 | 文件末尾 | 读从开头,写总是追加 |

问题1:打开文件,就是把文件加载到内存?

不是。fopen只是"建立连接,登记信息",文件内存还在硬盘里,根本没进内存。 打开文件=办个手续,不是把东西搬进来。只有调用读/写函数时,才加载。

文件的分类

Linux存在大量文件,分为打开的和没有被打开的,文件从位置上:1、内存级被打开的文件和没有被打开的。

文件从位置上,1、内存级被打开的文件 2、磁盘文件

Linux中,可以存在很多被打开的文件!

os如何管理这些文件呢?

三、Linux进行文件操作

1、打开文件open

open和它的参数介绍

运行结果:由于打开的这个文件不存在,所以要新建文件,但是新建文件需要设置文件权限,用第二个open。

所以必须对源文件进行修改:

结果是:

但是这个log.txt的权限是乱码,所以必须给它设置权限,此时就需要open的第三个参数

如下图:

此时他的权限就是正常的,如下:

但是这里的权限为什么是664呢?

那些因为在Linux系统里,里面会有umask权限掩码,它是002(八进制)--->000 000 010(二进制),权限666减去umask掩码002就是664.

此时可以改写系统的Umask掩码 如下:

再来看运行结果:这下权限都是可读可写权限了

umask

那么我们自己设置了umask掩码,系统里面也有umask掩码

2、关闭文件close

close使用方法

3、向文件描述符写write

open...库函数封装系统调用=内核不让你进,给你一层"安全外套"

O_TRUNC

你这里的 O_TRUNC 是 Linux 系统调用 open() 的一个标志位,,是 O_TRUNC(Truncate 的缩写)。

它的作用是:

  • 如果要打开的文件已经存在,并且是以只写或读写方式打开的,那么 O_TRUNC 会把文件的原有内容全部清空(截断为 0 字节),然后再写入新内容。

  • 如果文件不存在,这个标志位就没有效果。

简单来说, O_TRUNC 就是"清空重写"的意思,确保写入的内容是全新的,而不是追加到旧内容后面。

open() 常用标志位(如 O_RDONLY , O_WRONLY , O_CREAT , O_APPEND 等)

于是呢,我们就成功的将数据写进去了

此时,log.txt的内容是;

我们修改写入文件的内容:

在编译之前log.txt是有老内容的。如下图

在让这个文件运行。结果会从上次结果的开始进行覆盖式的。

修改:

之后重新编译运行,结果是:

O_APPEND

O_APPEND = 追加模式

  • 写文件时,永远从文件末尾写

  • 不会覆盖原来的内容,只在后面加

我们直接看效果:这就是追加后的结果

问题:这里的fd为什么是3呢?

答:在 Linux 中,每个进程启动时,系统会自动打开 3 个标准文件描述符:

  • 0 :标准输入(stdin)

  • 1 :标准输出(stdout)

  • 2 :标准错误(stderr)

当程序调用 open() 打开新文件时,内核会分配当前最小的未被使用的整数作为文件描述符。因为 0、1、2 已被占用,所以第一个新打开的文件,其文件描述符就是 3。

你看到的 fd: 3 ,就是程序中新打开文件的文件描述符。

库函数封装了系统调用

write(1,msg,strlen(msg)),1代表标准输出, msg指的是输出内容的指向。

运行结果:

问题:文件描述符的本质是什么?

答:数组下标

为什么要c封装,理解一下C的IO函数。

答**:你的程序
↑↓ (用 fopen / fread / fwrite / printf)
struct FILE (封装层:缓冲区、状态、方便操作)
↑↓ (真正干活:open / read / write)
操作系统内核(文件描述符 0 1 2 3...)**

C 语言 IO 总结

  1. 系统调用:open / read / write
  • 用 数字 fd(0、1、2、3...)

  • 直接跟操作系统打交道

  • 无缓冲、麻烦、效率低、只能读写字节

  1. C 标准库:FILE / fopen / printf / fread*
  • 是对上面系统调用的 封装

  • 用 FILE 结构体 * 管理一个文件(文件流)

  • 自带 缓冲区,速度快

  • 能格式化、按行、跨平台、好用

  1. 关系(最重要)
  • stdin / stdout / stderr 是 FILE*,不是数字

  • fileno(fp) 能从 FILE* 拿到 fd 数字

  • 封装 = 为了让你写代码更简单、更快、更安全

系统调用玩数字 fd,C 库玩 FILE 封装。

c封装好处

1. 有缓冲区,速度更快

不用每写一个字节就调用系统,减少开销。
2. 功能更强

能 printf 格式化、 fgets 按行读、 fscanf 解析数据。
3. 跨平台

Windows、Linux、mac 都能用同一套代码。
4. 更简单、更安全

自动帮你管错误、文件位置、状态,不用自己写底层。

为什么语言要有很好的跨平台性?

为了有更多的用户。

相关推荐
林姜泽樾2 小时前
linux入门第二章,linux命令基础、ls、home目录
linux
半桔2 小时前
【MySQL数据库】SQL 查询封神之路:步步拆解核心操作,手把手帮你解锁高阶玩法
linux·数据库·sql·mysql·adb·oracle
猫头虎2 小时前
[精选] 2025最新MySQL和PostgreSQL区别、迁移、安全、适用场景全解析
运维·数据库·mysql·安全·postgresql·云原生·容器
心本无晴.2 小时前
RAG检索优化:文本分块策略如何大幅提升检索准确度
java·linux·服务器
生活很暖很治愈3 小时前
Linux——线程互斥,互斥锁
linux·运维·服务器
小李独爱秋3 小时前
模拟面试:说一下数据库主从不同步的原因。
运维·服务器·mysql·面试·职场和发展·性能优化
白云偷星子3 小时前
RHCSA笔记7
linux·笔记
tryCbest3 小时前
Linux常用命令V2026
linux·运维
茶杯梦轩4 小时前
从零起步学习并发编程 || 第六章:ReentrantLock与synchronized 的辨析及运用
服务器·后端·面试