关于fd和fp(fd:file descirptor fp:file pointor)

通常,我们在输入数据或输出数据的设备为键盘或者显示器。当然,我们比较熟悉的输入输出,可能就是对于文件的操作,还有直接从终端输出,显示到显示器上。在C语言中,我们使用fopen,fclose,fread,fwrite对文件进行相应的操作。由于操作系统内核的不同,在linux系统下,我们不仅仅可以使用C库里边的那些函数,还使用open,close,read,write对文件进行相应的操作,这些都是系统调用的函数。它们之间有联系也有区别,现在我们分析一下吧。

C库:

(1)FILE *fopen(const char *path, const char *mode);

(2)int fclose(FILE *fp);

(3)size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);

(4)size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);

系统调用:

(1)

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);        //flags表示打开的方式,主要有O_RDONLY,O_WRONLY,O_CREAT,O_EXCL等
int creat(const char *pathname, mode_t mode); //如果打开不成功的话,就自己创建一个

我们看出,使用open函数的时候,调用的是系统的函数,而上述fopen是使用C库里边的函数。还有一点是open的返回值是整形,这也是与fopen不一样的。我们使用fopen的时候,它是返回一个file*,在这里,open的返回值是整形,它代表文件描述符。即唯一标识打开文件的信息。文件描述符是什么呢。我们之前在task_struct中介绍过PCB的基本信息。简单了解了PCB结构体中的信息后,我们发现在task_struct结构体中有一个files_struct结构体就是用于存放打开文件的一系列信息。

struct files_struct {/** read mostly part*/atomic_t count;   //自动增量  bool resize_in_progress;wait_queue_head_t resize_wait;struct fdtable __rcu *fdt;  struct fdtable fdtab;   //文件描述符表/** written part on a separate cache line in SMP*/spinlock_t file_lock ____cacheline_aligned_in_smp;unsigned int next_fd;  //下一个文件描述符unsigned long close_on_exec_init[1]; //执行exec时
需要关闭的文件描述符初值集合  unsigned long open_fds_init[1]; //当前打开文件
的文件描述符屏蔽字  unsigned long full_fds_bits_init[1];struct file __rcu * fd_array[NR_OPEN_DEFAULT]; //指向文件描述符组的指针
};

FILE的结构
struct _iobuf {char *_ptr;          //缓冲区当前指针int   _cnt;char *_base;         //缓冲区基址int   _flag;         //文件读写模式int   _file;         //文件描述符int   _charbuf;      //缓冲区剩余自己个数int   _bufsiz;       //缓冲区大小char *_tmpfname;};
typedef struct _iobuf FILE;

可以看到,files_struct中有一个文件描述符表,用来存放文件描述符。我们对于程序启动时默认会打开三个文件:stdin,stdout,stderr,它们的文件描述符分别表示:0,1,2。头文件unistd.h中有如下宏:

#define STDIN_FILENO 0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2

总结一下:

每个进程在linux内核中都有一个描述进程信息的结构体,称为task_struct。而描述进程的信息称为PCB,每个进程都有自己的PCB(进程控制块)。在task_struct结构体中,有一个指向files_struct的结构体指针,files_struct结构体中,描述了相应的文件描述符,I/O缓冲区,下一个文件描述符等。

说起库函数和系统调用,我们知道,最底层是硬件->驱动程序->操作系统->系统调用->shell外壳程序->库函数->用户程序;所以可以知道,库函数是在系统调用的基础上形成的,因此也知道open与fopen的关系了吧,fopen的底层也是调用了open的。

这里写图片描述

同理,看一下另外的read,write,close

ssize_t read(int fd, void *buf, size_t count);
ssize_t write(int fd, const void *buf, size_t count);
int close(int fd);

使用这些函数的时候,参数传入文件描述符来确定是哪个文件。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/382726.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

粗谈pragma once与 #ifndef的区别

#ifnde不受编译器的任何限制&#xff1b; #pragma once不受一些较老的编译器支持&#xff0c;兼容性不够好

在mac os10.13系统下 ,将py文件打包成可执行程序后, 里面的路径出现的问题

本来 用命令行运行py文件, 代码里面 获取当前路径的 语句 例如: os.getcwd() os.path.abspath(__file__) os.path.realpath(__file__)都可以获取到当前文件的路径, 但是打包成 可执行程序后, 统统不对了, 变成了 类似 /usr/xxx 的路径 https://stackoverflow.com/questions/50…

[linux]wait详解

wait&#xff1a;进程等待 主要有两种等待方式&#xff1a;阻塞式等待和非阻塞式等待 阻塞式等待&#xff1a;如果子进程正在运行&#xff0c;父进程将会一直等待着子进程运行结束&#xff0c;并且自己什么事都不干 非阻塞式等待&#xff1a;如果子进程正在运行&#xff0c;…

centos 使vim支持+python和+python3

本文为了给ycm服务&#xff0c;不单独存在。 查看是否支持python vim --version | grep python然后 下载vim8源码&#xff1a; git clone https://github.com/vim/vim.git 1 进行编译安装,添加python3和python2.7的支持&#xff1a; 进入下载的vim的源码文件夹中&#x…

ffmpeg的学习-00

命令行 大体样式 ffmpeg [global_options] {[input_file_options] -i input_url} ... {[output_file_options] output_url} ...有道翻译的 以后仔细回看 2.描述 ffmpeg是一个非常快的视频和音频转换器&#xff0c;也可以从一个实时音频/视频源抓取。它还可以转换之间的任意采样…

[Linux]消息队列

我们知道进程间通信的方法有多种&#xff0c;主要有管道&#xff0c;消息队列&#xff0c;信号量&#xff0c;共享内存&#xff0c;socket等。之前介绍过管道&#xff0c;今天再介绍一个新的概念–消息队列。 消息队列&#xff1a;将一个进程到另一个进程之间发送数据块的方式…

详解centos7 YCM YouCompleteMe自动补全安装,亲测成功

文章经重新排版转移至以下链接 https://blog.csdn.net/csdn_kou/article/details/84633663

python 异步与io

文档地址&#xff1a; https://docs.python.org/zh-cn/3/library/asyncio.html 以后再记录学习笔记 待续。。。

tornado 学习注意事项--00

设置url匹配的时候&#xff0c; (r/(.*), AMStaticFileHandler,dict(pathos.path.join(current_path, html), default_filenameindex.html))像这种语句要放到最后&#xff0c;因为放到前面的话&#xff0c; 后面的就无法匹配&#xff01;

C++关键字速查手册

[TOC] https://blog.csdn.net/csdn_kou/article/details/81113215 C98关键字 C11 关键字共73个 alignas alignof用于获取取指定表达式指定的&#xff08;类似sizeof&#xff0c;可以直接是类型名&#xff09;的对齐(alignment)。alignas用于声明时指定对齐类似于现有的类型…

[Linux]信号

Linux下的信号是一个什么概念呢。我们在现实生活中也遇到过信号之类的。比如红绿信号灯&#xff0c;班主任叫你去办公室并且脸色不好&#xff0c;诸如此类的都会给你一个信号。让你辨别事情的发生。同样&#xff0c;Linux下也有许多的信号&#xff0c;让你执行相应的操作。比如…

怎么用VLC播放器将m3u8链接视频下载到本地

转载 https://blog.csdn.net/saddyyun/article/details/85245135

【1】C++面试题函数引用重载宏命名空间

函数重载的条件 • 同一个名字 • 函数名字相同 • 参数列表不同 • 同一个作用域 为什么c支持函数重载而c不支持&#xff1f; c函数名字的修饰规则不一样。c编译器对函数修饰规则把int的参数列表形式加了进来&#xff0c;从而保证底层使用不同 cAdd(int a,int b)_AddcA…

[数据结构]Map和Set

说起map和set&#xff0c;想必我们都学过红黑树了吧&#xff0c;map和set就是红黑树的一个应用领域。它的底层就是由红黑树来实现的。下面简单说一下map和set的使用吧。 首先&#xff0c;有一个栗子是这样的&#xff0c;让我们统计出每种水果出现的次数。 我们会想到怎么解决…

js获取Json对象的长度

有两种Json形式&#xff1a; 第一种&#xff1a; var json1 {"data":[{"name":"zs","age":"10"}]};对于这种格式的json数据&#xff0c;如果想获取data的长度&#xff0c;就可以用以下这种方式&#xff1a; var length …

生产者消费者模型(条件变量)

三种关系&#xff1a;互斥&#xff0c;同步&#xff0c;互斥和同步 两类角色:生产者&#xff0c;消费者&#xff08;线程&#xff09; 一个交易场所&#xff1a;生产者消费者共享的区域 卖苹果的模型 dish上面只有一个苹果买家必须要等卖家把苹果放到dish上才可以去买苹果。…

linux之信号

信号&#xff1a;在生活中&#xff0c;我们遇到过不同种类的信号&#xff0c;比如&#xff1a;&#xff08;交通信号&#xff0c;乃至某个人的表情&#xff0c;动作等带给你不同的信号&#xff09;然而&#xff0c;在我们的linux下&#xff0c;我们最熟悉的就是&#xff0c;当遇…

视频解析有感,在解析 iqiyi与qq视频的时候,记录一些发现

最近对iqiyi与qq视频解析发现&#xff0c;两个网站的解析流程&#xff0c;尤其是反解析措施 各有特点&#xff0c;简单记录一下 先说iqiyi&#xff0c; 浏览器模拟移动端可以拿到视频的mp4链接&#xff0c;这个不多说。 iqiyiPC端浏览器获取 ts过程&#xff1a; a.iqiyi一次性…

C语言atoi函数的用法

#include < stdlib.h > int atoi(const char *nptr);用法&#xff1a;将字符串里的数字字符转化为整形数。返回整形值。 注意&#xff1a;转化时跳过前面的空格字符&#xff0c;直到遇上数字或正负符号才开始做转换&#xff0c;而再遇到非数字或字符串结束时(’/0’)才…

[Linux]继续探究mysleep函数(竞态条件)

之前我们探究过mysleep的简单用法&#xff0c;我们实现的代码是这样的&#xff1a; #include<stdio.h> #include<signal.h>void myhandler(int sig) {}unsigned int mysleep(unsigned int timeout) {struct sigaction act,oact;act.sa_handler myhandler;sigempt…