基础IO—02
1.文件描述符与文件流指针的关系
文件描述符:是一个非负整数—系统调用的IO接口。
文件流指针:FLIE结构体—库函数IO接口的操作句柄。
我们知道,库函数是对系统调用接口的一层封装。通过文件流指针进行最终文件操作的时候,依然还要能够找到文件对于的文件描述符才可以。文件流指针是一个结构体,结构体中有很多成员变量,其中就有一个叫_fileno,它就是文件描述符。
int main()
{
FILE* fp = fopen("./test.txt", "r+");
fp->_fileno = 1;//让该文件的文件描述指向标准输出
fwrite("hello world\n", 1, 12, fp);//终端会打印"hello world"
fclose(fp);
return 0;
}
向文件中写入数据,并不会直接写入文件,而是写入缓冲区中,刷新缓冲区的时候才会写入文件;系统调用接口是直接将数据写入文件的,系统调用接口没有缓冲区。缓冲区实际上是文件流指针结构体中的缓冲区。
2.文件系统
文件系统建设磁盘上管理文件的系统。(Linux下的ext2文件系统为例)
超级块:描述文件系统有多少磁盘块,有多少使用。
inode_bitmap:inode位图,用于分辨inode结点是否使用。
data_bitmap:data位图,用于分辨磁盘块是否使用。
inode:存储inode节点的区域。
data:数据储存区域。
inode节点:储存文件的元信息(大小,属性,所占磁盘块地址…)。
文件的存储流程:通过超级块找到inode位图/数据块位图,通过数据块位图快速的找到空闲的磁盘存储文件数据,通过inode位图快速找到空闲的inode节点存储文件的元信息。
在Linux下文件的数据和文件的名称是分离的,文件的数据存储完毕之后还需要在这个文件的所在目录下(目录文件),记录这个文件名称以及inode节点号。每一个文件都有一个唯一的inode节点。
获取文件数据流程:通过文件名打开一个文件,在所在目录文件中通过文件名找到这个文件的inode节点号。在磁盘超级块中找到inode节点区域,根据inode节点号快速找到inode节点,得到数据存储的磁盘块号,取出数据。
3.软/硬连接文件
软/硬连接文件:给一个源文件创建一个软/硬连接文件,就可以通过被创建出来的软/硬连接文件来操作源文件。
ln test.txt test.hard //为源文件创建一个硬连接文件
ln -s test.txt test.soft //为源文件创建一个软连接文件
软/硬连接文件的区别:
硬连接文件本质上和源文件没有什么区别,都是一个文件名称,与源文件共用同一个inode节点,通过自己的inode节点访问源文件数据。
软连接文件本质上是一个独立的文件,有自己的inode节点,文件数据中保存源文件的路径,通过这个路径访问源文件的数据。
1.删除源文件,软连接文件失效,硬连接文件知识链接数-1;链接数—一个inode节点对应有几个目录项。
删除一个文件,文件并不会立即删除,而是直接删除了目录项信息,inode中的连接数-1,直到链接数为0时才会真正删除文件。
2.软连接文件可以跨磁盘分区,硬连接文件不可以。
每个磁盘分区都有自己的文件系统,有自己的一套inode节点。跨分区建立硬连接与源文件inode节点号相同,这个节点号到底指向的是哪个分区的inode节点。
3.软连接文件可以对目录创建,硬连接文件不可以。
Linux下目录结构是唯一的,分区可以有多个,可以挂在不同的目录上,目录本身就是跨分区的,因此硬连接也就不能对目录创建。
4.动/静态库的打包与使用
库文件:打包了一堆实现了常用功能的代码文件。
//main.c文件
#include<stdio.h>
#include"child.h"
int main()
{
print_child();
return 0;
}
//child.h文件
int print_child();
//child.c文件
int print_child()
{
printf("hello\n");
return 0;
}
动态库的打包:动态库的命名方式lib***.so
gcc -c -fPIC child.c -o child.o
gcc -shared child.o libmychild.so
静态库的打包:静态库的命名方式lib***.a
gcc -c child.c -o child.o
ar -cr libmychild.a child.o
库的使用
生成可执行程序时链接使用:
gcc main.c -o main -lmychlid //-l指定库的名称
链接条件:
1.必须将库文件放到指定路径下:/usr/lib64 /usr/lib
2.设置链接库搜索路径环境变量-将当前库文件所在目录添加进去。
export LIBRARY_PAT=$LIBRARY_PATH:.
3.使用gcc -L选项指定链接库的搜索路径。
gcc main.c -o main -L./-lmychild
当目录下动态库和静态库同时存在时,系统默认使用动态库。加上-static链接静态库。
gcc -static main.c -o main -L./-lmychild
运行可执行程序时加载使用:仅仅针对动态库才会在运行时加载文件
加载条件:
1.必须将库文件放到指定路径下:/usr/lib64 /usr/lib
2.设置链接库搜索路径环境变量-将当前库文件所在目录添加进去。
export LIBRARY_PAT=$LIBRARY_PATH:.