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

相关推荐
clear sky .1 小时前
[linux]视频实时推流项目
linux·服务器·音视频
RisunJan2 小时前
Linux命令-nisdomainname(显示或设置系统的 NIS(Network Information Service)域名)
linux·运维·服务器
Wy_编程2 小时前
nginx测试
服务器·nginx
小此方2 小时前
Re:Linux系统篇(四)指令篇 · 三:两套打包压缩重要指令方法+剩余指令收尾
linux·运维·服务器
冷风阿健2 小时前
Linux 源码安装 Vim 9.2.0272 完整步骤(修复 CVE-2026-34714)
linux·运维·vim
w_t_y_y3 小时前
Claude Code(二)rules
linux·运维·ubuntu
白菜欣3 小时前
Linux —《从零上手Vim:核心用法全解析》
linux·编辑器·vim
小宏运维有点菜3 小时前
服务器 BMC 管理 IP
服务器·tcp/ip·centos
平行云3 小时前
虚拟直播混合式2D/3D应用程序实时云渲染推流解决方案
linux·unity·云原生·ue5·图形渲染·实时云渲染·像素流送