FILE
IO相关函数与系统调用接口对应,并且库函数封装系统调用,即从本质上讲访问文件都是通过fd访问的.
printf fwrite 库函数会自带缓冲区,而write 系统调用没有带缓冲区。另外,我们这里所说的缓冲区,
都是用户级缓冲区。其实为了提升整机性能,OS也会提供相关内核级缓冲区, printf fwrite 是库函数, write 是系统调用,库函数在系统调用的“上层”, 是对系统调用的“封装”,但是write 没有缓冲区,而printf fwrite 有,则有缓冲区是二次加上的,即是C标准库.
Linux下的文件系统–ext2
linux下ls -l命令所打印的数据每一行包括7列
模式 -> 硬链接数 -> 文件所有者 -> 组 -> 大小 -> 最后修改时间 -> 文件名
磁盘为块设备,硬盘分区划分为n个block,一个block可在初始化的时候进行更改,但是引导块(boot black)大小是确定的
- Block Group:ext2文件系统会根据分区的大小划分为数个Block Group。而每个Block Group都有着相同的结构组成。
- 超级块(Super Block):存放文件系统本身的结构信息。记录的信息主要有:bolck 和 inode的总量,未使用的block和inode的数量,一个block和inode的大小,最近一次挂载的时间,最近一次写入数据的时间,最近一次检验磁盘的时间等其他文件系统的相关信息。Super Block的信息被破坏,可以说整个文件系统结构就被破坏了
- GDT(块组描述符),Group Descriptor Table:描述块组属性信息
- 块位图(Block Bitmap):Block Bitmap中记录着Data Block中哪个数据块已经被占用,哪个数据块没有被占用
- inode位图(inode Bitmap):每个bit表示一个inode是否空闲可用。
- i节点表:存放文件属性 如 文件大小,所有者,最近修改时间等
- 数据区:存放文件内容
文件存储过程:
通过inode_bitmap在inode区域过去空闲inode节点,通过data_bitmap获取空闲数据块,在inode节点中记录文件信息以及数据块位置,并且将文件数据写入到数据块中
目录文件:
一个文件–文件中记录的目录的文件信息(文件名+inode节点号)—目录项
文件读取过程:
在目录项中通过文件名获取文件inode节点号(文件唯一),通过inode节点号在inode区域找到inode节点,通过inode节点中的数据块地址信息,在指定数据块读取数据
软连接和硬链接
软连接: ln-s srcfile destfile
相当于一个文件快捷方式,是一个独立的文件
硬链接: ln srcfile destfile
一个文件的名字(目录项),与源文件共用一个inode节点
区别:
硬链接删除文件两件事:
1.在目录中将对应的记录删除,
2.将硬连接数-1,如果为0,则将对应
的磁盘释放。
删除源文件,软链接文件失效;硬链接无影响(链接数-1)
软链接可以跨分区创建,硬链接不可以;
软链接可以对目录创建,硬链接不可以;
文件的三种重要时间
Access 最后访问时间
Modify 文件内容最后修改时间
Change 属性最后修改时间
stat命令查看文件时间:
touch命令:
-a 文件名 将access time恢复成系统时间。
-m 文件名 将modify time恢复成系统时间。
-c 文件名 将access time,modify time恢复成系统时间
-a 指定时间 文件名 将access time恢复成系统时间。
-m 指定时间 文件名 将modify time恢复成系统时间。
-c 指定时间 文件名 将access time,modify time恢复成系统时间。
-c -d 指定时间 文件名 将access time,modify time指定成指定时间
-m -d 指定时间 文件名 将modify time指定成指定时间
-a -d 指定时间 文件名 将access time指定成指定时间
静态库/动态库的生成与使用
Gcc编译过程:预处理,编译,汇编,链接
静态库(.a):程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静
态库
动态库(.so):程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。
一个与动态库链接的可执行文件仅仅包含它用到的函数入口地址的一个表,而不是外部函数所在目标文件的整个机器码
在可执行文件开始运行以前,外部函数的机器码由操作系统从磁盘上的该动态库中复制到内存中,这个过程称为动态链接(dynamic linking)
动态库可以在多个程序间共享,所以动态链接使得可执行文件更小,节省了磁盘空间。操作系统采用虚拟内存机制允许物理内存中的一份动态库被要用到该库的所有进程共用,节省了内存和磁盘空间。
动态库生成:
命名: lib是前缀, .so是后缀,中间是库名称
gcc -fplc -c child.c -o child.o
gcc –share child.o -o libmychild.so
静态库生成:
命名:lib是前缀, .a是后缀,中间是库名称
gcc -c child.c -o child.o
ar -cr libmychild.a child.o
-c 创建 -r模块替换
使用库链接库的时候,库文件有默认的搜索路径:/lib64/lib/usr/lib64
gcc main.c -o main -lmychild 报错:找不着库
-
将库文件放置到指定文件夹下 /lib64
-
设置环境变量
库文件的链接路径 : LIBRARY_PATH =
库文件的运行加载路径: LDLIBRARY_PATH = -
在使用gcc生成可执行文件是,直接指定库的搜索路径
gcc main.c -o main-l.-lmychild
gcc -l选项: 指定库的链接搜索路径
-I 选项: 指定头文件搜索路径想要使用第三方静态库,不能使用gcc的-atstic选项.因为-static选项是生成静态链接可执行程序,所有的库都使用静态库(但是我们只希望这个第三方库使用静态库,而不是所有) 因此我们将第三方静态库拷贝在指定路径下,使用-L选项指定库中的链接搜索路径那么这是候,链接的就是静态库