【Linux】--基础IO

一、C\C++中的文件操作

首先我们明确文件就是:文件的内容+文件的属性(元数据)

我们未来对于文件的操作无非就两种:

1、对内容进行操作

2、对属性进行操作

那么我们对文件进行操作,那么首先要先将文件打开,那么要先找到该文件,那么就需要路径+文件名。

那么我们有时候发现会有的直接使用的文件名的,这是因为文件的操作是由当前进程来完成的,那么就会使用这个进程的工作目录。

那么我们如何打开一个文件呢?

C语言中提供了一个接口:

1、fopen();

使用其要包含头文件:<stdio.h>

其函数原型如下:

FILE*fopen(const char*filename,const char* mode);

第一个参数:要打开的文件、可以选择带路径

第二个参数:打开文件的方式。

常见的打开方式如下:

"r":read只读打开,前提是文件已经存在

"w":write只写打开,但是其会先将文件中已经存在的内容先清空,然后再写入,如果文件不存在 那么就会先创建文件,然后再写入

"a":append追加写入、在这个文件的末尾开始写入内容,如果文件不存在,那么就会先创建这个 文件然后再进行写入

那么我们对于文件的写入,实际上是将字符串进行写入,那么我们的语言层面的话,字符串的最后一个字符是\0,这个\0可以不写入。

可以看到我们上面是没有任何文件的,下面我使用w的方式打开log.exe文件,然后我们看看当前路径下会不会创建一个文件:

可以看到在文件不存在的时候,读文件就会打开失败。

2、fwrite()

这个函数是对文件进行写入操作的。

其函数原型如下:

size_t fwrite(const void*prt,size_t size,size_t nmemd,FILE*stream);

第一个参数:我们要给文件写入的内容

第二个参数:要写入内容的大小

第三个参数:写入的次数

第四个参数:文件指针

补充:

C语言的程序执行的时候,其会默认打开三个输入输出流:stdin、stdout、stderr。

stdin:标准输入

stdout:标准输出

stderr:标准错误

标准输入,我们就认为是我们的键盘

标准输出、我们就认为是显示器

二、系统调用

在我们的操作系统中,我们也要对文件进行操作,操作系统提供的接口,我们叫做系统调用。

1、open()系统调用

这个接口是用来打开一个或者创建一个文件的、然后我们使用的时候要对文件的权限的信息进行设置。

函数原型如下:

int open(const char*pathname,int flags);

int open(const char*pathname,int flags,mode_t mode);

如果我们打开的是已经存在的文件,那么两个参数的就可以了。

要使用其要包含下面的几个头文件:

<fcntl.h>

<sys/stat.h>

<unistd.h>

第一个头文件是open这个系统调用的声明

第二个头文件是包含了文件权限的宏定义

第三个包含了read和write和close

下面我们来看其几个参数分别是啥:

第一个参数:要打开的或者创建的文件名

第二个参数:打开文件的方式,其主要为下面几个:

1、O_RDONLY:只读打开

2、O_WRONLY:只写打开

3、O_RDWR:可读可写

然后下面这几个就和上面的三种方式通过按位与(|)的方式一起使用。

1、O_CREAT如果文件不存在,就创建

2、O_EXCL:这个要和O_CREAT一起使用,如果文件已经存在,那么会报错,防止把原来的文件 覆盖了

3、O_TRUNC:如果文件已经存在而且文件是以写的方式打开的,那么就会先清空原来文件中的内 容

4、O_APPEND:每次写的操作都是追加到文件的末尾

5、O_NONBLOCK:非阻塞模式

第三个参数:当第二个参数为创建文件的时候,那么第三个参数就必须要写了。

这个是文件的权限掩码。

其是一个八进制数,然后文件实际上得到的权限掩码为mode-umask。

然后其返回值为:

打开成功的话,那么就会返回一个非负整数,一个非负整数就是文件描述符fd,一般都是3开始,因为一开始0、1、2就已经被使用了,然后我们的open返回的fd描述符,也是有规律的,返回那个最小的没被使用的。

打开失败就返回-1,然后会设置一个全局变量errno表示错误的原因。

2、write()系统调用

write是Linux和Unix操作系统下的系统调用,其是用于将内核内存缓冲区的数据写入到磁盘文件中的。

函数原型如下:

size_t write(int fd,const void *buff,size_t count);

其三个参数的详情如下:

第一个参数:文件描述符fd

第二个参数:表示我们要写出的数据的缓冲区指针

第三个参数:要写入的数据的大小,单位字节

其返回值为:

如果写入成功,那么就返回成功写入的字节数。

写入失败就返回-1。

补充:

write的写入其在写入完成后,会更新到写入的最后一个字节的下一个位置。

如果我们要更改其偏移量到文件的开始位置,那么我们可以使用lseek(int fd,int count,SEEK_SET)

三、文件的管理

上面我们讲到的是在语言层面上对文件的操作。

那么我们的操作系统对于文件是如何管理和组织的呢。

1、文件的管理

我们知道文件的创建和操作都是通过进程来完成的,我们的进程都会有一个task_struct结构体对象,在这个结构体对象中有一个FILE*的结构体指针,这个指针就是指向我们的文件描述表的

这个文件描述表其实际上是一个指针数组,存放的是文件的指针,来指向我们打开的文件,然后fd就是我们的这个数组的下标。

然后我们上面提到的三种标准输入输出,其打开就是占用了0、1、2.

0:标准输入

1:标准输出

2:标准错误

四、重定向

我们已经知道每一个进程中都会有一个文件描述表的存在。

文件描述表中,其就是一个数组,然后其存储的是文件指针,所以我们可以改变这个指针指向的地址,那么就改变了这个文件描述表这个位置的文件了。

系统中提供了dup2()这个接口,可以更改文件指针的下标位置。

其函数原型如下:

int dup2(int oldfd,int newfd);

其做的工作就是将oldfd这个下标位置的文件覆盖掉newfd这个位置。

其实就是让newfd这个指针指向oldfd这个位置指向的那个文件。

1、输出重定向

其操作符号:>

作用:将输出写入文件,而且会覆盖掉文件中的内容

其本质就是将我们的标准输入的fd和文件的fd使用dup2进行覆盖,那么我们的文件就在fd1这个位置上了,那么我们进行输入的时候,就变成了对这个文件进行写入。

2、追加重定向

操作符号:>>

作用:将输出信息写入到文件中,而且是在末尾追加

其实现原理就是使用dup2,将文件的fd变成1即可。

3、输入重定向

操作符:<

作用:从文件中读取内容输出

其实现原理也是一样的。通过修改文件的fd到2。

五、Linux下一切皆文件的理解

我们的操作系统要对各自的软件硬件进行管理,比如我们的键盘,显示器,网卡等等,那么我们要是对于每个资源都单独的去弄一个结构进行管理,那么就很冗余了。

所以操作系统会将其使用一个结构体封装起来,就比如将我们的read和wirte封装在一起,然后还有输出数组,输入数组等。

然后我们的各种硬件都会保持这种特性的前提下,然后又去根据自己的特点实现一些自己的属性。

相关推荐
桌面运维家2 小时前
IDV云桌面vDisk机房课表联动部署方案
大数据·服务器·数据库
StarryX2 小时前
Mac 用 UTM 装 Debian 实操教程(二)
linux
开开心心_Every2 小时前
扫描软件,部分文档文字表格识别功能可免费
运维·服务器·pdf·电脑·excel·3dsmax·houdini
陆伟峰(云固件作者)2 小时前
Linux Mint 22.3:给初学者的第一份 Linux 说明书
linux·运维·服务器
服务器专卖店3 小时前
2U双路通用机架服务器,均衡稳定,适配云计算、虚拟化、数据库等主流业务
服务器
SaN-V3 小时前
MacOS 下 VS Code 中 Codex 通过 SSH 连接远程服务器无法使用的问题排查与解决
服务器·macos·chatgpt·ssh·codex
顺风尿一寸3 小时前
深入 Linux 6.8.12 内核:x86_64 系统调用的快速路径与安全博弈
linux
齐潇宇3 小时前
Docker概述与安装
linux·运维·docker·容器
IP老炮不瞎唠4 小时前
IP轮换机制解析:动态住宅代理如何维持高可用率?
运维·服务器·网络