IO进程——系统IO与文件IO
在应用开发过程中会经常需要访问文件。Linux下读写文件的方式有两大类:标准IO和文件IO。
本次就来讲一讲文件IO和标准IO,以及两者的区别。
一、文件IO
在Linux系统中,大部分机制都会抽象成一个文件,这样,对它们的操作就像堆文件的操作一样。在嵌入式I/O变成是常用也是最基本的内容。
要了解文件I/O操作首先得知道文件的定义:
- 文件的定义:一组相关数据的有序集合
- 文件名:这个数据集合的名称
Linux下有7种类型的文件:
- 普通文件
d 目录文件
l 链接文件(ln -s :软链接)
p 管道文件
s 套接字文件
b 块设备文件
c 字符文件
以上文件类型在Linux通过命令查看
上图中蓝色框选中部分则是文件的类型;
Linux和Windows有所区别,Windows系统是以文件后缀名来判断文件类型,但Linux则是通过文件内容判断文件类型
(一) 文件 IO的定义
系统提供的一组操作文件的函数接口,文件的所有操作都有对应的函数来完成。
那文件都有哪些操作(操作文件数据)呢?
无非就是打开、关闭、读 、写、定位;
说到文件IO对文件的操作还需要了解文件描述符
文件描述符:
1. 一种非负整数(0-1023 共 1024个),内核用于区分 进程打开/访问的文件 的方式
2. 常见的三种特文件描述符标识: 0 1 2 是被系统占用的(标准输入、 标准输出、标准错误)
3. 文件io里面:在posix.1应用程序中,幻数0、1、2应被代换成符号常数STDIN_FILENO、STDOUT_FILENO、STDERR_FILENO。这些常数都定义在头文件<unistd.h>中。
文件IO使用的函数均为系统调用函数;系统调用和库函数关系如下图:
1、系统调用
1. 用户空间进程访问内核的接口
2. 把用户从底层的硬件编程中解放出来
3. 极大的提高了系统的安全性
4. 使用户程序具有可移植性
5. 是操作系统的一部分
2、库函数
1. 库函数为了实现某个功能而封装起来的API集合
2. 提供统一的编程接口,更加便于应用程序的移植
3. 是语言或者应用程序的一部分
3、文件IO常见的API接口
1、打开文件 ——open函数
函数原型:
int open(const char *pathname, int flags, mode_t mode);
2、关闭文件——close函数
函数原型:
int close(int fd);
3、文件读——read函数
函数原型:
ssize_t read(int fd, void *buf, size_t count);
4、文件写——write函数
函数原型:
ssize_t write(int fd, const void *buf, size_t count);
5、定位——lseek函数
函数原型:
off_t lseek(int fd, off_t offset, int whence);
二、标准IO
谈到标准IO,就得先知道什么是标准IO;
(一)、什么是标准IO
由c库提供的一组操作文件的接口函数 (在系统io基础上提供了缓冲机制的一组接口)
相比文件IO系统IO多出了缓冲机制,那先介绍一下缓冲区
1、缓冲的作用
1)存储金子塔
先看一下缓存金字塔,越往上存储速度是越快的;
2)标准IO和缓冲的关系:标准IO是把文件数据放到缓冲当中进行操作。避免直接读写磁盘。效率就得到提升。
2、标准IO三种缓存机制
标准I/O提供了三种类型的缓存
1. 全缓存
刷新(fflush):标准I/O的写操作。
当填满I/O缓存,或者满足一定的条件后,就会执行刷新操作。
2. 行缓存
当在输入和输出中遇到新行符(‘\n’)时,进行I/O操作。
当流遇到一个终端时,典型的行缓存。
3. 不带缓存
标准I/O库不对字符进行缓冲,例如stderr。
很多的人机交互界面要求不可全缓存。
标准出错决不会是全缓存的。
4. 使用setbuf()和setvbuf()可以更改缓存的类型
在任何时刻,可以使用fflush强制刷新一个数据流
5. 刷新流的3种情况:printf
刷新流的作用就是将缓冲区的文件数据写入到磁盘,有4种情况会刷新流:
1)程序结束,自动刷新缓冲区;
2)调用fclose()关闭了操作的文件,也会刷新缓冲区数据;
3)当缓冲区数据满时,也会刷新缓冲区文件数据到磁盘;
4)手动调用函数fflush刷新流。
3、标准IO函数接口
标准IO使用的函数均为库函数,和文件IO 使用的接口函数有所区别
1、打开文件
fopen、freopen函数
2、关闭文件
fclose函数
3、读写
1)按字符读写
按字符读:
putchar、fputc函数
按字符写:
getchar、fgetc函数
2)按行读写
按行读:
puts、fputs函数
按行写:
gets、fgets函数
3)按对象读写
按对象读:
fread函数
按对象写:
fwrite函数
4、定位
fseek、 ftell 、rewind函数
三、两者的区别
说了这么多,接下来说说文件IO和标准IO的区别
文件IO
1. 系统调用的一组 函数接口(偏向内核);
2. 没有缓存:读写效率较低,低级磁盘io;
3. 接口较少;
4. 受限制:在我们Linux系统下是可以使用的,但是在windows下是不可以。
5. 可以打开设备文件 ;
标准io
1.不能打开设备文件;
2. 在系统io 基础封装的一组 标准 函数接口(偏向用户);
3. 由缓存,读写效率较高 (高级磁盘io);
4. 接口更丰富。
上述这些就是我对文件IO以及标准IO的总结与对比;
关于文件IO和标准IO各种函数没有展开细讲,可以自己在Linux上查询相关函数用法;