1.标准库的IO接口:fopen/fwrite/fread/fseek/fclose
这里着重介绍一个fopen接口:
FILE * fopen(const char* filename,const char* mode)
mode:"r/r+/w/w+/a/a+"
1.w/w+:每次都会清空文件原有内容进行写入数据、如果原来没有这个文件的话,就会自行创建、加上+号就会变成可读可写的方式
2.fread/fwrite返回的都是块个数,而并非实际读取/写入的数据字节长度,因此使用时通常块大小为1,而块个数是数据长度,这样才能返回实际读取或写入的实际长度
2.系统调用接口:open/read/write/lseek/close
int open(const char* pathname,int flahs,mode_t mode);
pathname:带路径的文件名
mode:若有可能创建新文件则需要指定文件权限
flags:选项参数(必选项/可选项)
必选项:O_RDONLY/O_WRONLY/O_RDWR 只读/只写/可读可写 —三个选一个
可选项:
O_CREATE:文件不存在则创建新文件,存在则打开(使用这个必须用mode,加上权限)
O_EXCL:跟O_CREATE同时使用,若文件不存在则创建,存在则报错
O_TRUNC:打开文件的同时截断文件(清空原有的文件内容)
O_AOOEND:写入数据的时候总是追加在文件末尾
mode:r/r+/w/w+/a/a+
w+:O_RDWR | O_CREAT | O_TRUNC
a+:O_RDWR | O_APPEND | O_CREAT
open返回值:文件的操作句柄–文件描述符(正整数)
mode_t umask(mode_t mask);
umask设置文件的创建权限掩码,决定了文件的默认权限,计算方式–>给定权限 &~ 掩码
一旦可能新建文件,则一定要指定文件权限
ssize_t write(int fd,const void* buf,size_t count);
fd:文件描述符
buf:要写入文件的数据缓冲区首地址
count:要写入的数据长度
返回值:实际读取文件中的数据字节长度(不一定等于count),返回0表示读到文件末尾,失败返回-1
ssize_t read(int fd,void * buf,size_t count);
fd:文件描述符
buf:缓冲区首地址,放入取到的数据
count:要读取的数据长度(不一定等于count),返回0表示读到文件末尾,失败返回-1
off_t lseek(int fd,off_t offset,int whence)
例:lseek(fd,0,SEEK_SET)在读取数据之前将文件读写位置跳转到文件起始位置
int close(int fd);关闭文件,释放资源
3.文件描述符与文件流指针
文件描述符就是内核中的struct file fd_array[]数组的下标,进程可以通过这个下标找到文件的描述信息,进而操作文件*
文件描述符的分配规则:最小未使用
文件流指针与文件描述符的区别:
文件流指针结构中封装了一个文件描述符成员变量
文件流指针是库函数IO接口的操作句柄
文件描述符是系统调用IO接口的操作句柄
文件流指针这个结构体中封装了文件描述符
4.重定向
针对文件描述符所对应的文件描述信息的重定向,文件流指针与文件描述符没有改变,但是实际操作的文件却改变了
“>>”:追加重定向
“>”:情况重定向
dup2(fd,1)
5.文件系统:
超级块/inode bitmap/data bitmap/inode/data,对一个磁盘分区采用分块管理,提高利用率与查找效率
文件系统之中存储文件的流程:通过databitmap快速找到空闲的磁盘块,存储文件数据,通过inodebitmap快速找到空闲inode节点,保存文件元信息,将文件名和inode节点号作为目录项存储在文件所造目录的文件中
文件系统获取文件的流程:通过文件名在所在目录文件的目录项中找到文件名对应的目录项,从目录项中获取inode节点号,通过inode节点号,在文件系统的inodebitmap中获取inode节点,进而获取文件数据存储在磁盘的位置,进而获取到文件数据
6.软链接/硬链接
软链接文件:本质是一个独立的文件,有自己的inode节点,通过保存的源文件路径进而访问源文件,类似于window下的快捷方式
硬链接文件:跟源文件拥有相同的inode节点,类似于源文件的一个别名,通过自己的inode节点访问源文件
软链接删除源文件,则软链接失效,但是硬链接文件只是链接数-1
软链接可以针对目录创建,硬链接不可以
软链接可以跨分区建立,硬链接不可以
7.动态库与静态库
生成:
动态库的生成:
gcc -fPIC -c child.c -o child.o
gcc --share **.o… -o libmychild.so
静态库的生成:
gcc -c child.c -o child.o
ar -cr libmychild.a **.o…
使用:
1.将库文件放置到指定的文件路径下
2.设置链接库的环境变量
3.使用gcc -L +path 选项,告诉gcc库文件的搜索路径,gcc main.c -o main -L ./ -lmychild
仅针对动态链接生成的可执行程序:
1.将库文件放到指定的路径下
2.设置环境变量LD_LIBRARY_PATH–> export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:./
通常我们在链接静态库的时候,并不使用-static去指定gcc进行静态链接,因为-static的功能是在生成可执行程序的时候,所有的依赖库都是用静态库,而不是仅仅指定的哪个库。
所以通常在链接一个静态库的时候,都是将这个静态库放到指定路径下,就会直接链接这个静态库,而其他的依赖库依然会使用动态链接。