Linux之基础IO

1.C语言中的文件操作函数

文件的打开

path为文件路径,mode为打开方式,它们都是字符串。

代码演示:

此时,当前目录中并没有log.txt文件,但是没关系,fopen会在当前路径下创建log.txt文件。

简单来说,当前路径指的是一个进程运行起来的时候,每个进程都会去记录自己当前所处的工作路径。所以当前路径也就是当前进程的工作路径。

下面来验证一下:

注∶使用fopen时,填写mode参数,单纯以w方式打开文件,会自动清空文件原有的数据。r+(读写)代表文件不存在则出错, w+(读写)代表文件不存在则创建。(带有+的表示读写)。a代表向文件中追加内容。

打开文件方式的总结:

文件的关闭

C语言中的其它读写文件函数

int fputs(const char *s, FILE *stream);
char *fgets(char *s, int size, FILE *stream);

int fprintf(FILE *stream, const char *format, ...);
int fscanf(FILE *stream, const char *format, ...);

2.系统文件IO操作函数

1.open

pathname:打开文件名
flags :标志位。(打开文件时,可以传入多个参数选项,用一个或者多个常量进行"或"运算,构成 flags)

O_RDONLY:只读打开

O_WRONLY:只写打开

O_RDWR:读写打开
o_CREAT:若文件不存在,则创建它。需要使用mode选项,来指明新文件的访问权限O_APPEND:追加写
o_TRUNC:打开时,清空文件内容。
返回值: 成功则返回新打开的文件的文件描述符

失败:返回-1 ,并且errno被设置。

RETURN VALUE

open() and creat() return the new file descriptor, or -1 if an error occurred (in which case, errno is set appropriately).

flag如何传递多个选项,是通过比特位来传递选项的。

代码演示:

因此,我们可以使用|(或)来帮助我们传递多个参数,以此实现不同的功能。
mode参数

如果你使用O_CREAT参数创建一个新的文件,那么你还可以通过第三个参数mode来设置该文件的权限。

2.close
3.read

fd:要读取的文件

buf:存放读取内容的数组

count:读取的内容大小

4.write

fd:要写入的文件
buf:要写入的内容
count:所写内容的大小。

3.文件描述符fd

文件描述符的引入

代码演示:

运行结果:

fd是一个整数,我们发现,结果是从3开始的,为什么是从3开始的呢?

在C语言阶段,我们知道在程序运行时,操作系统会默认打开三个标准输入输出流:标准输入,标准输出,标准错误。对应到C语言当中就是stdin、stdout以及stderr。在C++中则是cin、cout、cerr。

我们知道C语言中的stdin、 stdoutl以及stder这三个家伙实际上都是FILE*类型的,并不是int类型。是因为FILE*是一个结构体指针,对fd进行了封装,而在Linux层面,只认fd。

代码验证:

结果如下:

对fd的理解

进程要访问文件,必须先打开文件,一个进程可以同时打开多个文件,操作系统中有大量的进程,也就是说操作系统要同时打开大量的文件,操作系统要对这些打开的文件进行管理,方式:先描述,再组织。

上边,我们发现fd是从0,1,2,3,4,.........

我们在哪里将从0开始的连续增长的整数--------数组下标。

其实,文件描述符的本质就是数组下标。

对应的内核部分代码:

4.文件描述符的分配规则

代码演示:

如果先关闭了0号文件描述符呢?

结论:

文件描述符是从最小并且没有被使用的开始分配的。

5.重定向

重定向的原理

(以输出重定向为例)

输出重定向的本质:

更改进程指向的files_struct内的struct file* fd_array[]数组内下标1内指向的struct file对象的地址。

重定向对应的系统调用

dup2

RETURN VALUE(返回值)

On success, these system calls return the new descriptor. On error, -1 is returned, and errno is set appropriately.

成功则返回新的文教描述符; 失败则返回-1,并且errno被设置。

代码演示:

结果:

关于dup2(int oldfd,int newfd)两个参数的填写

以上边的代码为例,目的是将本该打印到显示器的内容显示到log.txt文件中,结合对文件描述符的理解(文件描述符就是数组下标,struct file* fd_array[]数组内填写的是struct file对象的地址),再结合2号手册

我们不难理解到,我们是要把地址为fd对应的struct file地址拷贝到地址为1对应的位置,所以,要重定向的目标文件描述符在后(newfd), 要进行重定向的文件描述符在前(oldfd)。

6.理解Linux下一切皆文件

底层不同的硬件,一定对应不同的操作方法,但是OS管理这些底层硬件,使用统一的结构来进行管理的,在OS视角,底层硬件没有任何区别。

相关推荐
hello_ world.14 分钟前
RHCA10NUMA
linux
神秘人X70744 分钟前
Linux高效备份:rsync + inotify实时同步
linux·服务器·rsync
轻松Ai享生活1 小时前
一步步学习Linux initrd/initramfs
linux
轻松Ai享生活1 小时前
一步步深入学习Linux Process Scheduling
linux
绵绵细雨中的乡音3 小时前
网络基础知识
linux·网络
Peter·Pan爱编程3 小时前
Docker在Linux中安装与使用教程
linux·docker·eureka
kunge20134 小时前
Ubuntu22.04 安装virtualbox7.1
linux·virtualbox
清溪5494 小时前
DVWA中级
linux
Sadsvit5 小时前
源码编译安装LAMP架构并部署WordPress(CentOS 7)
linux·运维·服务器·架构·centos
xiaok5 小时前
为什么 lsof 显示多个 nginx 都在 “使用 443”?
linux