Linux屏蔽了硬件的区别,把所有的硬件设备都抽象成文件,提供统一的文件接口给用户使用。
虚拟文件系统
抽象层,对文件的访问实际上是对抽象层的访问
封装了底层读写细节,使用C语言的多态来实现文件系统的接口。
普通文件系统
ext4
fat32
ubifs
特殊文件系统
进程文件系统:procfs, 挂载在/proc,存放进程相关信息《任务管理器》
设备文件系统:devfs,挂载在/dev。存放硬件操作接口
procfs是“process filesystem”的缩写,所以它 也被称为进程文件系统,procfs通常会自动挂载在根 目录下的/proc文件夹。procfs为用户提供内核状态和进程信息的接口,功能相 当于Windows的任务管理器。在《查看系统信息》章节我们也尝试过/proc目录查看一些系统信息。
文件名 | 作用 |
pid* | *表示的是进程的 PID 号,系统中当前运行的每一个进程都有对应的一个目录,用于记录进程所有相关信息。对于操作系统来说,一个应用程序就是一个进程 |
self | 该文件是一个软链接,指向了当前进程的目录,通过访问/proc/self/目录来获取当前进程的信息,就不用每次都获取pid |
thread-self | 该文件也是一个软链接,指向了当前线程,访问该文件,等价于访问“当前进程pid/task/当前线程tid”的内容。。一个进程,可以包含多个线程,但至少需要一个进程,这些线程共同支撑进程的运行。 |
version | 记录了当前运行的内核版本,通常可以使用命令“uname –r” |
cpuinfo | 记录系统中CPU的提供商和相关配置信息 |
modules | 记录了目前系统加载的模块信息 |
meminfo | 记录系统中内存的使用情况,free命令会访问该文件,来获取系统内存的空闲和已使用的数量 |
filesystems | 记录内核支持的文件系统类型,通常mount一个设备时,如果没有指定文件系统并且它无法确定文件系统类型时,mount会尝试包含在该文件中的文件系统,除了那些标有“nodev”的文件系统。 |
文件名 | 文件内容 |
cmdline | 只读文件,记录了该进程的命令行信息,如命令以及命令参数 |
comm | 记录了进程的名字 |
environ | 进程使用的环境变量 |
exe | 软连接文件,记录命令存放的绝对路径 |
fd | 记录进程打开文件的情况,以文件描述符作为目录名 |
fdinfo | 记录进程打开文件的相关信息,包含访问权限以及挂载点,由其文件描述符命名。 |
io | 记录进程读取和写入情况 |
map_files | 记录了内存中文件的映射情况,以对应内存区域起始和结束地址命名 |
maps | 记录当前映射的内存区域,其访问权限以及文件路径。 |
stack | 记录当前进程的内核调用栈信息 |
status | 记录进程的状态信息 |
syscall | 显示当前进程正在执行的系统调用。第一列记录了系统调用号 |
task | 记录了该进程的线程信息 |
wchan | 记录当前进程处于睡眠状态,内核调用的相关函数 |
Hankin
2020.07.16
常用头文件
在后面的学习中我们常常会用到以下头文件,此处进行简单说明,若想查看具体的头文件内容,使用locate命令找到该文件目录后打开即可:
· 头文件stdio.h:C标准输入与输出(standard input & output)头文件,我们经常使用的打印函数printf函数就位于该头文件中。
· 头文件stdlib.h:C标准库(standard library)头文件,该文件包含了常用的malloc函数、free函数。
· 头文件sys/stat.h:包含了关于文件权限定义,如S_IRWXU、S_IWUSR,以 及函数fstat用于查询文件状态。涉及系统调用文件相关的操作,通常都需要用到sys/stat.h文件。
· 头文件unistd.h:UNIX C标准库头文件,unix,linux系列的操 作系统相关的C库,定义了unix类系统POSIX标准的符号常量头文件,比如Linux标准的输入文件描述符(STDIN),标准输出文件描述符(STDOUT),还有read、write等系统调用的声明。
· 头文件fcntl.h:unix标准中通用的头文件,其中包含的相关函数有 open,fcntl,close等操作。
· 头文件sys/types.h:包含了Unix/Linux系统的数据类型的头文件,常用的有size_t,time_t,pid_t等类型。
系统IO编程(系统调用)
open
write
read
lseek
close
演示代码:
int fd;
fd = open(filename, flags, mode);
lseek(fd, offset, whence);
write(fd, buf, write_len);
read(fd, buf, read_len);
close(fd);
文件描述符
特殊的索引:实际上就是进程中的file_struct结构体成员fd_array的数组下标
进程:每个程序本质上就是一个进程
文件打开模式
主模式:
表 flag参数值
标志位 | 含义 |
O_RDONLY | 以只读的方式打开文件,该参数与O_WRONLY和O_RDWR只能三选一 |
O_WRONLY | 以只写的方式打开文件 |
O_RDWR | 以读写的方式打开文件 |
O_CREAT | 创建一个新文件 |
O_APPEND | 将数据写入到当前文件的结尾处 |
O_TRUNC | 如果pathname文件存在,则清除文件内容 |
副模式:
O_CREATE:当文件不存在,需要去创建文件
O_APPEND:追加模式
O_DIRECT:直接IO模式
O_SYNC:同步模式
O_NOBLOCK:非阻塞模式
OPEN函数
函数原型
1 2 3 4 5 | #include #include #include int open(const char *pathname, int flags); int open(const char *pathname, int flags, mode_t mode); |
Linux打开文件,默认是有 0 :标准输入, 1:标准输出, 2:错误模式,,,所以我们只能申请到3的句柄
CLOSE函数
函数原型
1 2 3 4 5 | #include <unistd.h> int close(int fd); 返回值: 成功:0 失败:-1 |
read函数
1 2 | #include ssize_t read(int fd, void *buf, size_t count); |
read函数用于从文件中读取若干个字节的数据,保存到数据缓冲区buf中,并返 回实际读取的字节数,具体函数参数如下:
· fd:文件对应的文件描述符,可以通过fopen函数获得。另外,当一个程序 运行时,Linux默认有0、1、2这三个已经打开的文件描述符,分别对应了标准输入、标准输出、标准错误输出,即可以直接访问这三种文件描述符;
· buf:指向数据缓冲区的指针;
· count:读取多少字节数据
返回值:
· count:成功读取全部字节
· 0~count:剩余文件长度小于count,,,读取期间被异步通信打断
· -1:读取错误
write函数
1 2 | #include ssize_t write(int fd, const void *buf, size_t count); |
write函数用于往文件写入内容,并返回实际写入的字节长度,具体函数参数如下:
· fd:文件对应的文件描述符,可以通过fopen函数获得。
· buf:指向数据缓冲区的指针;
· count:往文件中写入多少个字节。
返回值
count:成功写入全部字节
0~count:写入期间被异步通信打断
-1:写入数据失败
1、打开要复制的文件
2、创建新的文件
3、把源文件的内容读到缓冲区,把缓冲区 内容写入新的文件中
4、循环执行第三步,直到读取的字节数量为0,退出循环
5、关闭已经打开的文件
运行copy代码后,将1.txt的内容复制到2.txt
lseek函数
头文件
#include
lseek函数可以用于设置文件指针的位置,并返回文件指针相对于文件头 的位置。其函数原型如下:
1 | off_t lseek(int fd, off_t offset, int whence); |
它的用法与flseek一样,其中的offset参数用于指定位置,whence参数则定义了offset的意义,whence的可取值如下:
· SEEK_SET:offset是一个绝对位置。
· SEEK_END:offset是以文件尾为参考点的相对位置。
· SEEK_CUR:offset是以当前位置为参考点的相对位置。
使用vim编辑器查看数据内容,和预期的效果一致。
sync函数
头文件
#include
其函数原型如下:
1 | void sync(void); 返回值:无 |
功能:强制将修改过的页缓存区数据写入磁盘
标准IO编程(glibc库)
C语言标准库实现了一个IO缓存区
fopen对标系统open
fclose对标系统close
fread对标系统read
fwrite对标系统write
fseek对标系统seek
fflush对标系统sync
文件IO五大模式
1、阻塞模式
2、非阻塞模式
3、IO多路复用
4、异步IO
5、信号驱动IO
Hankin
2020.07.17