linux基础IO
基础文件IO
C库的文件IO操作接口:fopen 打开文件 fclose 关闭文件 fread 读取 fwrite 写入 fprintf 格式化写入
fseek函数:移动跳转当前读取/写入位置
SEEK_SET 从文件起始位置开始偏移
SEEK_CUR 从文件读写位置开始偏移
SEEK_END 从文件末尾位置开始偏移
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
man open
pathname: 要打开或创建的目标文件
flags: 打开⽂文件时,可以传⼊入多个参数选项,用下面的一个或者多个常量进行“或”运算,构成flags。
参数:
O_RDONLY: 只读打开
O_WRONLY: 只写打开
O_RDWR : 读,写打开
这三个常量,必须指定一个且只能指定⼀一个
非必选项:
O_CREAT : 若⽂文件不存在,则创建它。需要使用mode选项,来指明新文件的访 问权限
O_EXCL: 与O_CREAT同用时,若文件存在则报错
O_TRUNC: 若文件存在则将文件长度截断为0
O_APPEND: 追加写
返回值:
成功:新打开的文件描述符(非负整数),后续操作都需要通过文件描述符完成
失败:-1
标准输入 标准输出 标准错误输出
stdin stdout sterr
0 1 2
描述符和文件流指针的关系
文件流指针用于库指针操作io
文件描述符用于系统调用接口io
库函数是对系统调用的一层封装
文件流指针结构体中包含了一个成员也就是文件描述符
文件流指针中还定义了一个缓冲区,所谓刷新缓冲区,这个缓冲区是库函数独有的,用于将短小数据组合成大数据一次性写入文件,这样可以提高效率。而系统调用则没有这个缓冲区
换行刷新缓冲区仅针对于标准输出,对文件没有用
文件描述符:(是一个数字)
是一个进程中对打开文件的描述信息的结构体数组的下标
文件描述符的分配方式:最小的未使用结构体数组节点下标
输入输出重定向:本质上来说就是将一个下标所对应的文件描述替换成另一个文件的描述
标准输入输出重定向:
< 输入重定向
> 输出重定向 清空原有内容后添加新数据
>> 输出重定向 在原有内容的下方添加新数据
FILE结构体:这个结构体中其实有一个成员是文件描述符,这个结构体中还有一个用户态的缓冲区
Linux下文件系统:
超级块 inode位图 data位图 inode节点区 数据区
软链接和硬链接
软链接:是一个单独的文件,有自己的目录项,inode节点,数据区
可以看做是一个快捷方式,通过这个软连接文件可以找到另一个位置的其他文 件,软连接文件是linux下的一个特殊文件(符号链接文件),这个文件所保存 的数据就是指向的另一个文件的路径名,这个软链接文件通过路径名来定位所 指向的文件。
硬链接:更像是一个文件的别名,有自己的目录项,没有单独的inode节点和数据区
它的inode节点和数据区和源文件是相同的。一个文件,每多一个硬链接,它 的inode节点中有一个链接数属性都会+1,代表这个inode节点对应了好几个 文件名,可以通过任意一个文件目录项访问到相同的inode节点。
删除一个文件时,实际上是先将inode节点中的链接数-1操作,当这个链接数 为0时,代表这个文件是真的被删除了,这时候才会释放inode节点和数据区。
软链接与硬链接的区别:
1. 软链接是一个单独的文件,有自己的inode节点;
硬链接是和原文件使用相同的inode节点。
2. 软链接可以对目录进行创建
硬链接则不可以
3. 删除原文件后,软链接将断开连接,找不到这个文件
硬链接不受影响,只是inode中的链接数-1
4. 软链接可以跨分区
硬链接不可以
动态库和静态库
静态库(.a):程序在编译链接的时候把库的代码链接到可执⾏行⽂文件中。程序运⾏ 行的时候将不再需 要静态库
动态库(.so):程序在运⾏行的时候才去链接动态库的代码,多个程序共享使⽤用库的代码。
动态库命名方式libc.so --lib是前缀,. so是后缀
静态库命名方式libc.a --lib是前缀,.a是后缀
gcc默认的库连接方式是动态库链接
生成:需要将源码文件编译成自己的目标文件(动态库也可以gcc直接从源码生成生成), 也就是从 .c => .o
最终这些 .o 文件连接在一起是生成动态库或者静态库或者可执行程序,这取决于连接过程
如果要生成的是一个库文件,则代码中不能有main函数
如果要生成的是一个可执行程序,则代码中有且只能有一个main函数
静态库生成:
将所有的 .o 文件打包到一起生成,打包的命令: ar -cr lib***.a *.o
-c 创建
-r 模块替换
动态库生成:
- -share 是生成动态库的gcc链接选项,没有这个将认为是生成可执行程序
将所有的 .o 打包,生成命令:gcc - -share -o lib***.so *.o
要生成一个动态库,gcc编译器告诉我们,在编译阶段将一个 .c => .o 需要加上一个编译选项 gcc -fPIC -c *.c -o *.o
-fPIC : 产生位置无关代码
动态库是一个运行时库,需要在程序运行的时候也加载到内存中,并这个加载的过程是操作系统干的,会去指定位置加载动态库,因此我们需要将动态库放到指定位置才可以运行程序 /lib /lib64
链接动态库/静态库:gcc *.c -o main -L./ -ltest 链接一个库生成可执行程序
gcc链接选项:-L 用于指定库的查找路径
-I 用于指定链接的库名称(去掉前缀和后缀)