Linux —— 基础IO - 文件描述符

目录

[1. 背景补充](#1. 背景补充)

[2. 理解"文件"](#2. 理解“文件”)

[2.1 狭义理解](#2.1 狭义理解)

[2.2 广义理解](#2.2 广义理解)

[2.3 文件操作的归类认知](#2.3 文件操作的归类认知)

[2.4 系统角度](#2.4 系统角度)

[3. 复习C文件接口](#3. 复习C文件接口)

[3.1 以 C语言"w" 方式打开文件:](#3.1 以 C语言“w” 方式打开文件:)

[3.1.1 实现清空文件的操作](#3.1.1 实现清空文件的操作)

[3.2 以 C语言"a" 方式打开文件:](#3.2 以 C语言“a” 方式打开文件:)

​编辑

[3.3 实现cat命令](#3.3 实现cat命令)

[3.4 系统](#3.4 系统)

[3.5 输出信息到显示器,你有哪些方法](#3.5 输出信息到显示器,你有哪些方法)

[4. 库文件操作和系统调用](#4. 库文件操作和系统调用)

[​编辑4.1 用系统调用实现 "w" 的方式](#编辑4.1 用系统调用实现 "w" 的方式)

[4.2 用系统调用实现"a"的方式](#4.2 用系统调用实现"a"的方式)

[4.3 结论](#4.3 结论)

[4.4 open()返回值:文件描述符](#4.4 open()返回值:文件描述符)


基础IO:重点理解文件相关的内容!!!

1. 背景补充

2. 理解"文件"

2.1 狭义理解

  • 文件在磁盘里
  • 磁盘是永久性存储介质,因此文件在磁盘上的存储是永久性的
  • 磁盘是外设(即是输出设备也是输入设备)
  • 磁盘上的文件本质是对文件的所有操作,都是对外设的输⼊和输出 简称 IO

2.2 广义理解

Linux 下⼀切皆是文件(键盘、显示器、网卡、磁盘...... 这些都是抽象化的过程)(后面文章会提如何去理解)

2.3 文件操作的归类认知

  • 对于 0KB 的空文件是占用磁盘空间的
  • 文件是文件属性(元数据)和文件内容的集合(文件= 属性(元数据)+ 内容)
  • 所有的文件操作本质是文件内容操作和文件属性操作

2.4 系统角度

  • 对文件的操作本质是进程对文件的操作
  • 磁盘的管理者是操作系统
  • 文件的读写本质不是通过 C 语言 / C++ 的库函数来操作的(这些库函数只是为用户提供方便),而是通过文件相关的系统调用接口来实现的

3. 复习C文件接口

运行结果:

但是当我们修改了当前工作路径的话,文件就会被建在新的指定的路径下,哪又该如何修改文件的路径呢?

使用 chdir 命令:

此时进程对应的当前工作路径改变了:

所以打开文件本质是:进程在打开。所以:

打开文件,必须要找到文件,要找到文件,就必须知道该文件的路径+文件名,这就是为什么进程要有cwd的原因之一!!!所以cwd是查找文件的默认路径!!所以:#include<>查头文件,是在系统的路径下找,找不到再到当前的路径下找;#include " " 默认在当前的路径下找,编译器会帮忙找的,因为编译器跑起来是一个进程。因为编译器也有自己的cwd,所以#include " " 默认在当前的路径下找。

在打开文件时,任何时候,只有文件名打开文件,当前都会有路径,因为进程会自动记录下来。同样在vs中,编译的时候启动编译器,编译器就是一个进程,有进程就有当前路径,有当前路径就能在当前路径下找头文件。

3.1 以 C语言"w" 方式打开文件:

运行结果:

多次运行结果一直不变:

在 log.txt 文件中手动写入一些内容:

原来的文件的内容变短了。

3.1.1 实现清空文件的操作

那么想写一个进行清空文件的软件应该如何写呢?

上述代码,实现将文件打开,在关闭就实现了自动清空的功能。

3.2 以 C语言"a" 方式打开文件:

3.3 实现cat命令

在文件中加了一些内容:

再次查看log.txt文件:

所以cat命令在打印一个文件的时候,如何将文件的内容打印出来的呢?

cat log.txt 的时候,cat 命令就有命令行参数将对应的log.txt传到cat进程里面了,之后cat命令在shell当中就会创建子进程,父进程fork之后exec让cat将文件打开,进行打印。

3.4 系统

3.5 输出信息到显示器,你有哪些方法

写二进制就直接往文件中写入,写文本类文件是要进行格式化输入输出的,显示器和键盘进行读写只认字符,读进来的是字符转换成整数,输出的时候是字符转换成整数再打印,这就是格式化输入和输出。打印字符串的话,字符串本身就不用转换了,显示器和键盘都认为是一个一个的字符,所以计算机中才有一张表结构:ASCII码表,ASCII码表是数字和图形的关系,printf转为字符'1''2''3''4''5'之后,1字符就是一个整数,在查对应的ASCII码表,就可以得到1字符的显示的格式,显示器在查找ASCII码表,再将ASCII码表中的1字符显示出来。汉字、中英文也好都是符号。

显示器读写其实是文本读写。

想向显示器文件打印字符串:

运行结果:

以上接口都可以向显示器中显示。

所以真正的打开文件,调用的不是C语言的接口:fopen,而是fopen底层封装的open()系统调用来打开文件。

4. 库文件操作和系统调用

运行结果:

4.1 用系统调用实现 "w" 的方式

运行结果,返回的是没有此文件或目录

以写的方式打开文件时,文件不存在时,是会创建一个新的文件,没错,但那是C语言。我们使用 O_WRONLY 发现文件新建不了,如果要新建一个不存在的文件时,加上 O_CREAT。

但是可以看见 log.txt 的权限是乱码,这是要指明该新建文件的权限是多少:

可以看见我们设置的权限是666,但是显示出来的 log.txt 文件权限是664,因为系统中存在umask,umask会限制掉对应的权限,把other的写去掉了。

但是我们非得创建出一个权限为666的文件,如何操作?

同时,umask是不受影响的:

在代码中新建文件,设置权限时,所使用的掩码就近原则,如果用户设置了umask就合权限进行权限运算,如果没有设置权限就采用系统的umask。

系统调用有点像C语言,用系统调用也可以向文件写入:

log.txt 文件没有清空,而是将里面的内容能够覆盖多少就覆盖多少,C语言中是清空了的,但是系统调用默认是没有清空的。我们想将文件内容进行清空呢?

此时,如果我们只进行打开文件,关闭文件的操作,不做写入的话,就会达到将文件清空的作用。

运行结果:

4.2 用系统调用实现"a"的方式

追加方式打开文件,文件不存在,也会帮我们新建文件:

4.3 结论

由 4.1 和 4.2 得到的结论:

4.4 open()返回值:文件描述符

open() 返回的是整数。

运行结果:

上面的 3、4、5、6代表的是什么?

所以 3、4、5、6代表的是数组的下标,所以 write(fd,...) 和 close(fd,...)必须得传递文件描述符,上面的图属于OS内部,在OS内部,OS识别被打开的文件,OS只认:fd

相关推荐
AOwhisky11 分钟前
MySQL 学习笔记(第一期):数据库基础与 MySQL 初探
运维·数据库·笔记·学习·mysql·云计算
Peace11 分钟前
【Prometheus】
linux·运维·prometheus
LZZ and MYY2 小时前
RTS 在windows和Linux之间ShareMem
linux·运维·服务器
aningx2 小时前
openSUSE Leap 16.0 运行 sunshine 报错的解决方法
linux
爱学习的徐徐2 小时前
Linux 基础IO
linux·服务器
蛋蛋的学习记录2 小时前
C#窗体应用中使用EasyModbusCore通讯
服务器·c#·tcp
zt1985q2 小时前
本地部署源代码管理解决方案 Bitbucket Data Center 并实现外部访问
运维·服务器·数据库·网络协议·postgresql·源代码管理
xiaobobo33302 小时前
面向对象:linux内核中函数转数据的用法
linux·面向对象·隔离·函数指针绑定
极客先躯2 小时前
高级java每日一道面试题-2026年01月18日-实战篇[Docker]-如何清理仓库中的旧镜像?
java·运维·docker·容器
姓刘的哦2 小时前
C++软件架构设计思路
linux