IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发工具 -> 文件流指针和文件描述符 -> 正文阅读

[开发工具]文件流指针和文件描述符

1.文件流指针和文件描述符的产生

fopen函数打开文件成功后会返回文件流指针,open函数打开文件成功后返回的是文件描述符.他俩的相同点是通过文件流指针和文件描述符都可以对文件进行操作.

2.fopen函数和open函数的介绍

fopen函数(库函数)

path:带有的路径的文件名,如果没有路径默认在当前文件下.

mode:

'r' 只读方式打开,将文件指针指向文件头,如果文件不存在,则返回空。
'r+' 读写方式打开,将文件指针指向文件头,如果文件不存在,则返回空。
'w' 写入方式打开,将文件指针指向文件头并将文件内容清空。如果文件不存在则创建。
'w+' 读写方式打开,将文件指针指向文件头并将文件内容清空。如果文件不存在则创建。
'a' 写入方式打开,将文件指针指向文件末尾。如果文件不存在则创建。
'a+' 读写方式打开,将文件指针指向文件末尾。如果文件不存在则创建。
例如:FILE* fp = fopen("1.txt", "w+");

open函数(系统调用函数)

pathname:带有的路径的文件名,如果没有路径默认在当前文件下.

flags:打开文件时,可以传入多个参数选项,用下面的一个或者多个常量进行“运算,构成flags

参数 :
O_RDONLY: 只读打开
O_WRONLY: 只写打开
O_RDWR : 读,写打开
? ? ? ? 这三个常量,必须指定一个且只能指定一个
O_CREAT : 若文件不存在,则创建它。需要使用 mode 选项,来指明新文件的访问权限
O_APPEND: 追加写
返回值: 成功:新打开的文件描述符,失败返回-1
例如:int p=open("1.txt", O_RDONLY|O_CREAT,0664);两个宏之间用 位图运算,0664是打开的文件的权限

3.文件描述符的介绍和怎么查看文件描述符

文件描述符是打开文件后返回的值,通过文件描述符可以操作文件,而每一个进程在运行时都会默认打开标准输入,标准输出,表述错误.这三个文件描述符.

打开一个文件然后进入死循环

int p=open("11.txt",O_RDWR | O_CREAT,0664);
    if(p<0)
    {
        return 0;
    }
    while(1)
    {

    }

用pa aux | grep mytext查看进程号

ll .proc/进程号/fd? ? ?查看进程打开的文件描述符.

?

?0:标准输入

1:标准输出

2:标准错误

3:程序里打开的文件的文件描述符

文件描述符就相当于文件的标记:标记的规则是最小数规则

在打开文件之前关闭标准输入文件,

?

?0代表的文件被关闭,所以打开文件后1.txt文件的文件描述符就是0;

4.从内核角度理解文件流指针和文件描述符

文件描述符:

每一个进程在内核里都是一个struct task_struct结构体:

结构体里看到了我们熟悉的pid

这是一个struct files_struct指针(描述的是当前进程打开文件的信息)

这个结构体指针指向的struct files_struct类型的变量,变量里里有一个struct file_rcu*fd_array[NR_OPEN_DEFAULT],这个结构体指针数组里的数组下表就是文件描述符,数组当中的元素是指针类型,指向了文件,所以通过文件描述符,就可以找到对应的文件.

图文关系如下:

文件流指针:

FILE可以在stdio.h的头文件里使用说明这个指针在这个文件里存在.直接cd /usr/include

打开包含头文件的文件夹,vim stdio.h.就能看到这个头文件里有啥了...(.h文件里基本上都是声明)

?

?第一个struct _IO_FILE是一个结构体的声明;

第二个是FILE指针是被重命名出来的,他的本来面目是struct _IO_FILE这个结构体

找到struct _IO_FILE结构体的办法:

在include文件下面进行搜索,grep struct _IO_FILE . -R(意思是在当前文件下进行递归搜索)

?打开结构体定义对应的文件libio.h,找到结构体的定义:

?char* _IO_read_ptr; ? /* Current read pointer */? ? ?表示当前读到了哪个位置
?char* _IO_read_end; ? /* End of get area. */? ?表示当前读区域的末尾
char* _IO_read_base; ?/* Start of putback+get area. */? 表示读区域的起始位置
char* _IO_write_base; /* Start of put area. */? ? ? 写缓冲区的起始位置
char* _IO_write_ptr; ?/* Current put pointer. */? ? ? ?写到了哪个位置
char* _IO_write_end; ?/* End of put area. */? ? ? ? ? 写缓冲区的末尾位置

文件描述符里包含这些指针,在文件进行读写的时候告诉函数应该从哪读;

int _fileno;? 保存文件描述符的数值,

代码验证

#include<stdio.h>

int main()
{
    FILE*fp=fopen("1.text","w");
    printf("%d\n",fp->_fileno);
}

结果是

标准输入标准输出和标准错误分别是0,1,2,根据最小值规则,文件的文件标识符就是3

?图文匹配

struct _IO_FILE{...}这个结构体是标准库当中的结构体,该结构体里上述的指针维护的缓冲区是标准库的缓冲区

5.文件描述符和文件流指针的关联

上述说到文件描述符是PCB里的一个数组的的下标,所以一个PCB里可以有多个文件描述符.等同于,PCB里包含进程打开的所有文件...而文件流指针的范围就比较小了,一个文件流指针只能保存一个文件的文件描述符,就是文件流指针只能代表一个文件.所以一个进程至少要打开三个文件,标准输入,标准输出,标准错误.

图文对比

?

?

  开发工具 最新文章
Postman接口测试之Mock快速入门
ASCII码空格替换查表_最全ASCII码对照表0-2
如何使用 ssh 建立 socks 代理
Typora配合PicGo阿里云图床配置
SoapUI、Jmeter、Postman三种接口测试工具的
github用相对路径显示图片_GitHub 中 readm
Windows编译g2o及其g2o viewer
解决jupyter notebook无法连接/ jupyter连接
Git恢复到之前版本
VScode常用快捷键
上一篇文章      下一篇文章      查看所有文章
加:2022-03-10 22:48:06  更:2022-03-10 22:50:00 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 6:35:56-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码