一.linux 打开文件三层结构关系图
文件描述符、打开文件表、inode 关系图

其中磁盘文件属性在inode,内容在缓冲区
1. 文件打开与创建
通过文件名来打开文件,不存在文件就会创建新的文件。文件都是具有权限的,所以我们需要进行权限的定义。
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
// 打开已有文件
int open(const char *pathname, int flags);
// 创建+打开文件(带权限mode)
int open(const char *pathname, int flags, mode_t mode);
第一个参数是文件名,第二个参数是文件的打开方式,第三个参数是文件权限掩码。
2. 文件关闭
文件打开后需要及时关闭。
#include <unistd.h>
int close(int fd);
参数是文件描述符,一个进程的整数编号。
3. 文件写入
文件需要进行写入操作。
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
4. 文件再次写入
4.1 清空写入
与常规语言不一样,很多是默认清空的,但是这里需要手动清空,要不然会出现覆盖之前的内容。
第一个参数是文件描述符,第二个参数是需要写入内容缓冲区的起始地址,第三个参数是写入内容的大小。
使用宏定义映射 O_TRUNC 选项。
// 再次打开,O_TRUNC 会清空之前文字,重新写
int fd2 = open("test.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);
char buf2[] = "覆盖后的新内容\\n";
write(fd2, buf2, strlen(buf2));
close(fd2);
return 0;
4.2 结尾追加写入
使用宏定义映射 O_APPEND 选项。
// 再次打开追加
int fd2 = open("log.txt", O_WRONLY | O_CREAT | O_APPEND, 0666);
write(fd2, "第二条日志\\n", strlen("第二条日志\\n"));
close(fd2);
return 0;
默认写入的是字符串,将整数写入会变成乱码,需要写入时还是需要转化为字符串。
5. 文件读取
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
fd 参数是文件描述符,一个进程的整数编号。
6. 文件描述符与标准流
FILE* 返回值里面封装了文件描述符 fd,例如 stdin、stdout、stderr 这些对应的是 0、1、2。
7. 重定向
更改文件描述符的指针指向。
8. 重定向原理
文件描述符的分配规则:最小的、没有被使用的,作为新的 fd 给用户。
int dup2(int oldfd, int newfd);
作用:让 newfd 指向 oldfd 所关联的文件
例子:
int dup2(3, 1);
重定向之后可以进行close(oldfd)
重定向的方式可以是清空重定向,追加重定向,同样的使用O_TRUNC,O_APPEND选项.
所以重定向就是:打开文件的方式(追加,只读等)+dup2(从哪里到哪里,使用文件描述符)
- > 标准输出重定向(覆盖)
- >> 标准输出重定向(追加)
- < 标准输入重定向
重定向一定是子进程进行重定向
重定向细节
当从标准输出重定向到一个指定文件log.txt时,1和2指向的标准输出和错误都是同一个显示器
./out.cc > log.txt //其中的1会省略,即标准输出
./out.cc 1 > log.txt //当你使用标准erro时,还是会显示到显示器上面
./out.cc 1 > log.normal 2>log.erro
为什么需要存在一个标准错误:可以通过重定向的能力,把常规消息和错误消息进行分离.
如果我们不想将标准错误和标准输出的内容进行分开
./out 1>log.txt 2>>log.txt //使用追加重定向
./out 1>log.txt 2>&1 //让2(标准错误)完全复制 1 号通道。
9.引用计数
基础定义
引用计数:内核给「文件表项」设置一个数字,记录当前有多少个文件描述符指向这同一个文件表。
二.理解"一切皆文件"
我们只要拿到上层的文件描述符就可以通过struct file里面的函数指针(指向函数方法,读写等)来访问不同的硬件(键盘,磁盘等),就是c版本的多态
1.缓冲区
缓冲区就像一个快递站,在你忙碌的时候可以将你的包裹暂存,不至于停下手中的工作. 提高各方的效率.
什么是缓冲区:内存的一段空间
在c标准库中会有用户级的语言缓冲区,使用库函数(printf,fprintf.fput,fwrite)并不是直接到文件内核缓冲区,当用户(强制刷新,刷新条件满足,进程退出)的时候才会通过(fd+系统调用write等)进入到内核缓冲区,fd可以找到对应文件,在满足条件的时候就可以通过fd找到对应文件写入内核缓冲区再写入到对应的硬件
一个文件都要有自己的缓冲区,FILE是一个结构体,里面有fd和缓冲区指针
2.缓冲的几种方式:
1.立即刷新—无缓冲—写透模式WT
2.缓冲区满了—全缓冲—缓冲区最满,效率最高!(普通文件)
3.行刷新—行缓冲(显示器)
系统调用是有成本的,所以我们通过语言缓冲区来加快效率
我们只要将数据交给OS,就相当于交给了硬件!数据交给系统,交给硬件—本质全是拷贝!计算机流动的本质:一切皆拷贝
网硕互联帮助中心



评论前必须登录!
注册