一、什么是文件I/O与标准I/O
文件I/O:文件I/O的函数通常称之为不带缓存的I/O(unbuffered I/O)
标准I/O:指的是ANSI C建立的一个标准I/O模型,是一个标准函数包和stdio.h头文件中的定义,其提供三种类型的缓存:
1.全缓存:当填满标准I/O缓存后才进行实际I/O操作。(磁盘上的文件通常由I/O标准可部署为全缓存)
2.行缓存:当输入和输出种遇到换行符或填满缓存时,标准I/O才执行I/O操作。(处理终端的输入输出时就是使用的行缓存)
3.不带缓存:即标准I/O库不对字符进行缓存。(标准出错就是不带缓存的类型)
二、两者的区别
文件I/O 又称为低级磁盘I/O,标准I/O其内部实际上就是调用文件I/O来进行实际的文件操作,只是其内部多了缓存
操作,这样做的目的在于减少实际的read,write的操作。其只有在缓存满足相应的条件时才进行read,write操作,
减少了实际系统调用的次数。
文件I/O中使用文件描述符来表示一个打开的文件
标准I/O中使用的是FILE(流)来表示一个打开的文件
| 标准I/O | 文件I/O |
---|
打开 | fopen,freopen, fdopen | open |
关闭 | fclose | close |
读 | getc,fgetc,getchar;fgets,gets; fread | read |
写 | putc,fputc,putchar;fputs,puts;fwrites | write |
定位 | fseek,ftell | lseek |
三、文件I/O函数
1.open函数
#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);
pathname自然不用说,flags却有许多可选选项,分别为:
O_APPEND 以追加方式打开文件,每次写时都写在文件末尾。
O_CREAT 如果文件不存在,则创建一个,存在则打开它。
O_EXCL 与O_CREAT一起使用时,如果文件已经存在则返回出错。
O_TRUNC 以只写或读写方式打开时,把文件截断为0
O_DSYNC 每次write时,等待数据写到磁盘上。
O_RSYNC 每次读时,等待相同部分先写到磁盘上。
O_SYNC 每次write时,等到数据写到磁盘上并接更新文件属性。
而mode只有在文件创建才用到,用于指定文件访问权限:
S_IRWX[UGO] 可读 可写 可执行
S_IR[USR GRP OTH] 可读
S_IW[USR GRP OTH] 可写
S_IX[USR GRP OTH] 可执行
S_ISUID 设置用户ID
S_ISGID 设置组ID
也可使用数字表示,如 0777,0644等直接表示相应的权限
2.close函数
#include <unistd.h>
int close(int fd);
3.creat函数
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int creat(const char *pathname, mode_tmode);
其mode与read中使用到mode相同
creat创建文件相当于以只写方式创建一个文件,文件若存在则将文件截断为0
4.lseek函数
#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
whence可选选项为:
SEEK_SET,则offset从文件的开头算起。
SEEK_CUR,则offset从当前位置算起,既新偏移量为当前偏移量加上offset
SEEK_END,则offset从文件末尾算起。(可用于生成空洞文件)
offset为偏移量
5.read函数
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
6.write函数
#include <unistd.h>
ssize_t write(int fd, const void *buf,size_t count);