php网站美化,建设工程公司 网站,百度竞价怎么做,wordpress手机版有什么用1.前置知识#xff1a;
#xff08;1#xff09;文章 内容 属性
#xff08;2#xff09;访问文件之前#xff0c;都必须打开它#xff08;打开文件#xff0c;等价于把文件加载到内存中#xff09; 如果不打开文件#xff0c;文件就在磁盘中
#xff08;3
1文章 内容 属性
2访问文件之前都必须打开它打开文件等价于把文件加载到内存中 如果不打开文件文件就在磁盘中
3谁会去访问一个文件进程。进程被加载启动之后运行到fopen才会打开一个文件
4手绘的进程和文件系统之间的交互图 必看 2.C语言fopen函数 #include stdio.hFILE *fopen(const char *path, const char *mode); path: 指向你想要打开的文件路径的字符串。mode: 字符串指定文件的打开模式。 打开模式 mode 参数决定了文件是如何被打开的。常见的模式有 r: 只读方式打开文本文件。文件必须存在。w: 只写方式打开文本文件。如果文件存在则将其截断为零长度如果文件不存在则创建新文件。a: 追加方式打开文本文件。如果文件存在则在文件末尾添加数据如果文件不存在则创建新文件。rb, wb, ab: 分别对应上面的二进制文件版本。r, w, a: 对应的读写版本既可读也可写。rb, wb, ab: 读写模式下的二进制文件版本。 3.系统级接口open open系统级接口我们熟知的fopen是C语言的语言级接口fopen底层封装的就是open #include fcntl.hint open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode); pathname: 指向你想要打开或创建的文件路径的字符串。flags: 这个参数可以包含多个标志的按位或组合用于指定文件的打开方式例如只读、只写、读写等。mode: 当创建新文件时通过使用了 O_CREAT 标志这个参数指定了新文件的权限模式。 常见标志 O_RDONLY: 只读方式打开文件。O_WRONLY: 只写方式打开文件。O_RDWR: 读写方式打开文件。O_CREAT: 如果指定的文件不存在则创建之。O_TRUNC: 如果文件存在并且以写方式或者读写方式打开则将其长度截断为0。O_APPEND: 每次写操作前都会将文件指针移动到文件末尾。 返回值 成功时open 函数返回一个新的文件描述符失败时返回 -1 并设置 errno 来指示错误类型。 4.文件描述符open函数的返回值 操作系统中只认识 “文件描述符” 0代表打开文件失败 0 1 2 分别代表 键盘文件标准输入显示器文件标准输出显示器文件标准错误流 接下来打开的文件顺序是从3号开始 每一个进程执行到open创建struct file结构体然后在file_struct数组中一个位置连接这个struct_file结构体就会把数组的下标作为返回值fd1, 放回给进程。fd的分配规则最小的没有被使用的fd 1. 创建struct file结构体 2. 数组链接结构体 3. 把数组下标返回给进程 5. C语言对操作系统中的文件操作进行了两个封装 1.接口封装 fopenC语言级接口 - open系统级接口 2.类型封装 FILE 结构体里面肯定包含文件描述符- int 文件描述符下标 6. 为什么语言层面还要进行封装 1.方便用户操作 open需要使用各种标识O_RDONLY... 而fopen使用打开模式r 2.不用考虑平台的切换提高语言的可移植性linux windows的open不同但fopen一样 7.理解struct file结构体 最重要的三个部分1.inode结构体指针 2.文件操作的结构体指针 3.文件内核级缓冲区指针 1inode结构体
当文件从磁盘加载到内存的时候这个inode表就要被创建。 在磁盘中文件 属性 内容。 inode中的数据就是拷贝磁盘中文件的属性。 当我讲那些没有被打开的文件时我还会重谈inode表中的索引指针 2文件操作表
保存文件操作的函数指针。进程中的write()会调用struct file - f_op -write -写入内核级缓冲区
由操作系统决定什么时候将内核级缓冲区中的数据写入到磁盘。系统级接口 fsync ( fd )可以刷新内核级缓冲区 3 文件内核级缓冲区 文件内核级缓冲区完全由操作系统管理旨在提供高效、可靠的文件I/O操作同时尽量减少用户空间应用对此过程的干预需求。这种设计使得大多数应用程序无需关心底层存储细节即可获得良好的性能表现。 8. 输入输出重定向 close(1); file1.txt printf(“hello”); fflush(stdout); //一定要执行这个操作才会把内容写入到file1.txt中也不显示到显示器上。 //如果没有执行fflush内容不在file1.txt中也不在显示器上显示。 首先我们先不管fflush假设他会写入到file1.txt中这是为什么呢
因为close1会把显示器文件关闭然后打开file1.txt是返回最小的没有被使用的fd那就是1了。这样子printf只认识fd1的就会写入到file1.txt文件中。
然后为什么需要fflush(stdout)stdout其实就是fd 1fflush是刷新语言级别的缓冲区 这里引入一个新概念语言级别缓冲区 输出重定向 int dup2(int oldfdint newfd ) //但是这里有认知偏差如果要把1覆盖 dup2(fd,1); 在数组中把新的地址浅拷贝到原先的地址当上层使用文件描述符下标的时候就会重定向到目标文件 dup2还会把多余的指向目标文件的指针进行清除没人指向的那一个一般会自动关闭 oldfd 和 newfd都是 文件描述符。 你也可以不使用fflush来刷新而是使用fclose来刷新因为fclose不但封装了close系统调用而且还封装了fflush。 那么为什么close不能自动刷新呢因为fflush是刷新语言级缓冲区而close是系统级调用语言级缓冲区还在系统调用之上close根本就看不到语言级缓冲区。 9.语言级别缓冲区 因为在写入或者读取的时候不断访问内核级缓冲区调用系统调用会有明显的消耗。所以在语言层面还有一个语言级别的缓冲区。当我们printf的时候只是写入到语言级缓冲区还需要使用fflush写入到内核级缓冲区中。 语言级别缓冲区的三种刷新方式 显示器文件 行刷新 遇到 \n 刷新写入磁盘文件普通文件缓冲区写满再刷新不缓冲直接调用系统接口