通常,我们在输入数据或输出数据的设备为键盘或者显示器。当然,我们比较熟悉的输入输出,可能就是对于文件的操作,还有直接从终端输出,显示到显示器上。在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);

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

关于fd和fp(fd:file descirptor fp:file pointor)相关推荐

  1. c语言file和fp未声明标识符,c语言定义文件指针时(FILE *fp)一定要写*fp吗、可以换成别的字母不...

    c语言定义文件指针时(FILE *fp)一定要写*fp吗.可以换成别的字母不 关注:146  答案:4  mip版 解决时间 2021-01-29 07:27 提问者祗剩寂寞 2021-01-28 1 ...

  2. <Linux基础--文件描述符fd、重定向、文件流指针FILE*概念理解>

    文章目录 1.文件描述符fd 2.重定向 3.文件流指针:FILE* 4.动态库和静态库 1.文件描述符fd 文件描述符:实际上就是内核中一个进程打开的文件描述信息数组(file* fd_array[ ...

  3. 松下FP系列程序 松下FP系列程序,搭配松下伺服,昆仑通态触摸屏锂电池全自动叠片贴胶机

    松下FP系列程序 松下FP系列程序,搭配松下伺服,昆仑通态触摸屏锂电池全自动叠片贴胶机 大型程序近30000步,三个PLC,主从站通信控制 ,隔膜放卷纠偏控制,正负极真空取料叠片控制,可设定叠片层数, ...

  4. caffe libcudnn.so.6: cannot open shared object file: No such file or directo

    更新cudnn版本至cuDNN v6 ImportError: libcudart.so.6.0: cannot open shared object file: No such file or di ...

  5. java new file 路径_File file = new File(路径名) 路径名的2种写法

    项目的结构:相同颜色是同级的 bean的配置文件的读取和一般文件的读取有点差别的 public static void getValue(String key){ //传入"time&quo ...

  6. libgstreamer-1.0.so.0: cannot open shared object file: No such file or directory

    1. 问题现象 error while loading shared libraries: libgstreamer-1.0.so.0: cannot open shared object file: ...

  7. android file mkdir,android file.mkdir()一直返回false问题

    今天想写本地日志,结果写文件的时候一直失败,报FileNotFound错误,很明显,就是文件创建失败的问题了,debug了一下,发现在创建路径的时候,file.mkdirs()就出问题了(这个方法相对 ...

  8. OSError: libcudart.so.8.0: cannot open shared object file: No such file or directory 解决方法

    OSError: libcudart.so.8.0: cannot open shared object file: No such file or directory 解决方法 检查cuda8是否安 ...

  9. 调用torchtext报错OSError: libtorch_cpu.so: cannot open shared object file: No such file or directory

    环境 torch版本1.4.0 报错 报错信息如题.调用torchtext报错 OSError: libtorch_cpu.so: cannot open shared object file: No ...

最新文章

  1. cdn加速的原理是怎么样的
  2. 为Java + STANDARD值引入Cucumber
  3. 腾讯视频上如何上传视频
  4. C#.NET通用权限管理在DB2数据库上运行的脚本参考 - 通过程序将数据导入到目标数据库中...
  5. python大鱼吃小鱼程序代码_最近跟导师学Python,熬夜弄了两个晚上写出来个大鱼吃小鱼游戏!...
  6. BZOJ.3489.A simple rmq problem(主席树 Heap)
  7. 【AtCoder-2164 C】Rabbit Exercise AtCoder【差分找规律+倍增】
  8. 父与子的编程之旅---1出发吧2记住内存和变量3数学运算45输入6GUI7判断8转圈圈9注释
  9. [高通MSM8909][Android7.1]电信卡信号优化
  10. 《穿越计算机的迷雾》读书笔记
  11. 选中的磁盘具有MBR分区表,在EFI系统上,windows只能安装到GPT磁盘
  12. 微信开发 完美微信自动转发朋友圈-flutterAndroid
  13. CDR服装设计-旗袍款式图
  14. java使用水晶报表,java处理水晶报表
  15. 后台界面也可以很酷!31个高大上的后台管理系统模版
  16. 使用fedora32桌面图标
  17. 手机端自适应表格table样式如何写
  18. python工资自动发放_python自动化办公--协助财务自动发送工资条
  19. python外文文献翻译_英文学术文献翻译软件有哪些推荐?
  20. mysql 配置自动截断_MySql超长自动截断

热门文章

  1. Zookeeper实现注册与发现
  2. Illustrator、Indesign与Photoshop
  3. HTTPS协议在Tomcat中启用的配置
  4. 【腾讯Bugly干货分享】Android内存优化总结实践
  5. POJ 3233 Matrix Power Series 矩阵快速幂 + 二分
  6. Linux中后台执行scp
  7. 广元南山隧道南河互通立交图_广元城区一隧道工程竣工时间已定,今后出行更加方便了!...
  8. php送数据找不到表,php – 数据源默认值中找不到的模型表
  9. finditerable 转list_java – 通过拆分和运行将ListenableFuture转换为Iterable
  10. promise将ajax变为同步,ES6-Promise改造异步请求为同步