镜缘浮影 小人本住在 苏州的城外 家里有屋又有田 生活乐无边

标准I/O (一).fopen

2016-12-26
wilmosfang
c
原文地址 http://soft.dog/2016/12/26/c-stdio-01/

前言

当前的计算系统除了包括对数据有 加工和处理 以外还有 搬运

这个 搬运 代表着 输入和输出 ,及 input/output ,简称 I/O

UNIX/Linux 的缔造者们将数据的 来源和目标 都抽象为 文件,所以在 UNIX/Linux 系统中 一切皆文件

一切皆文件 不仅仅对磁盘,还包括鼠标,键盘,显示器这些设备,那么对这些设备的操作也都抽象成了对 文件的I/O操作

这里分享一下我在学习 UNIX I/O 库过程中的笔记和心得


概要


标准I/O

将常用的处理过程封装成库以供其它模块调用,可以有效降低计算系统内各部件之间的耦合度,增强系统的健壮性和可移植性

不仅是UNIX,很多其它操作系统都实现了标准I/O库,所以这个库由ISO C标准说明 (# include <stdio.h> 中包含了标准I/O库)

标准I/O库处理很多细节,如缓冲区分配,以优化的块长度执行I/O等操作,这些工作帮助开发者将注意力从这些琐碎繁杂的事务中抽出,投放到更有价值的业务逻辑中

Tip: 标准I/O库是在1975年左右编写的,35年来几乎没有被修改过,后人发现里面存在很多不足,其中很大一个不足就是效率不高,所以后来又有很多的替代包,然而许多标准I/O库的实现在C函数库中可用,这种C函数为内存较小的系统(如嵌入式系统)设计的,这些实现对于合理内存要求的关注超过了对可移植性、速度以及功能性等方面的关注,所以成为了其合理存在的原因

Note: 标准I/O库并不完善,它有很多不足,一些属于基本设计,但是大多数则与各种不同的实现有关,标准I/O库使用了缓冲技术,而这正是产生很多问题,引起许多混淆的部分


fopen

File *fopen(const char*path,const char *mode)

操作系统最多可以打开多少个文件

#include <stdio.h> //标准IO库在这里

int main()
{
  int i=0;
  FILE *fp; 
  while((fp=fopen("xx","w+")))i++; //不断打开文件xx,直到打开不了(fopen函数返回空指针),过程中使用i进行计数
  printf("%d\n",i); //将计数结果进行打印
  return 0;
}

fopen 的返回值是,文件顺利打开后,指向该流的文件指针就会被返回,若打开文件失败则返回NULL,并把错误代码存在errno中

以上的代码中,为NULL会导致while判断为条件不成立,从而跳出循环,停止计数

如果文件指针不断被打开而不释放(fclose()) , 在程序结束前就会逐渐耗尽系统资源

Note: 文件打开数是一种系统资源,是有上限的,虽然程序退出后,系统会帮忙清理,但在程序设计中,打开文件,使用完后进行手动关闭是一种很好的习惯,这样可以有效避免缓存未刷新的潜在隐患

编译执行

emacs@ubuntu:~/c$ alias gtc
alias gtc='gcc -Wall -g -o'
emacs@ubuntu:~/c$ gtc openfile.x openfile.c
emacs@ubuntu:~/c$ ./openfile.x 
1021
emacs@ubuntu:~/c$ 

为什么是 1021 呢,默认系统中是可以打开 1024 个文件的

emacs@ubuntu:~/c$ ulimit -n
1024
emacs@ubuntu:~/c$ 

从0开始最大文件描述符就是1023,然而 0、1、2 分别已经被 标准输入,标准输出,标准错误输出 占据了,所以剩下的还有 1021 个可用资源

原文地址 http://soft.dog/2016/12/26/c-stdio-01/

评论