文件IO
1、文件IO与标准IO:
标准IO:
标准I/O是ANSI C建立的一个标准I/O模型,是一个标准函数包和stdio.h头文件中的定义,具有一定的可移植性。标准IO库处理很多细节。例如缓存分配,以优化长度执行IO等。标准的IO提供了三种类型的缓存。
(1)全缓存:当填满标准IO缓存后才进行实际的IO操作。
(2)行缓存:当输入或输出中遇到新行符时,标准IO库执行IO操作。
(3)不带缓存:stderr就是了。
文件IO:
文件IO称之为不带缓存的IO(unbuffered I/O)。不带缓存指的是每个read,write都调用内核中的一个系统调用。也就是一般所说的低级I/O——操作系统提供的基本IO服务,与os绑定,特定于linix或unix平台。
区别
首先:两者一个显著的不同点在于,标准I/O默认采用了缓冲机制,比如调用fopen函数,不仅打开一个文件,而且建立了一个缓冲区(读写模式下将建立两个缓冲区),还创建了一个包含文件和缓冲区相关数据的数据结构。低级I/O一般没有采用缓冲,需要自己创建缓冲区,不过其实在linix或unix系统中,都是有使用称为内核缓冲的技术用于提高效率,读写调用是在内核缓冲区和进程缓冲区之间进行的数据复制。
其次从操作的设备上来区分,文件I/O主要针对文件操作,读写硬盘等,它操作的是文件描述符,标准I/O针对的是控制台,打印输出到屏幕等,它操作的是字符流。对于不同设备得特性不一样,必须有不同api访问才最高效。
2、文件IO的主要函数:
open, close, read, write, lseek、hup, dup2, fcntl, pread, pwrite
open函数:
#include <fcntl.h> int open(const char * pathName, int flags, .../*mode_t mode*/);
成功返回文件描述符,失败返回-1
返回的文件描述符的当前未使用的最小描述符
flags:
必选参数:O_RDONLY、O_WDONLY、O_RDWR
可选参数:O_APPEND、O_CREAT、O_EXCL、O_TRUNC、O_NOBLOCK、O_NOCTTY
close函数:
#include <unistd.h> int close(int fildes);成功返回0, 失败返回-1
read函数:
#include <unistd.h> ssize_t read(int fd, void * buf, size_t len);
参数:
fd:打开的文件描述符;
buf:读取数据存放缓冲区;
len:缓冲区的大小
return:
成功返回读取到的缓冲区大小
0:表示读取到文件末尾
-1:调用失败
write函数:
#include <unistd.h> ssize_t write(int fd, const void * buf, size_t len);
参数:
fd:打开的文件描述符
buf:将要写的数据缓冲
len:数据缓冲区的大小
lseek函数:
off_t lseek(int fd, off_t offset, int whence);参数:
实例1:模仿linux/unix的copy指令:
#include <fcntl.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> const int MAX_BUF_LEN = 4096; int main(int argc, char * argv[]) { if(3 != argc) { printf("命令格式不正确!\n"); return -1; } int fdRead = open(argv[1], O_RDONLY | O_CREAT | O_EXCL, 0664); if(-1 != fdRead) { printf("源文件不存在!\n"); close(fdRead); char buf[255] = {0}; sprintf(buf, "rm %s", argv[1]); system(buf); return -2; } fdRead = open(argv[1], O_RDONLY); if(-1 == fdRead) { printf("open error:源文件打开错误!\n"); return -3; } int fdWrite = open(argv[2], O_WRONLY | O_CREAT | O_EXCL, 0664); if(-1 == fdWrite) { printf("open error: 创建目标文件失败!\n"); fdWrite = open(argv[2], O_WRONLY | O_TRUNC); if(-1 == fdWrite) { return -4; } } while(true) { char buf[MAX_BUF_LEN] = {0}; int nReadLen(0), nWriteLen(0); nReadLen = read(fdRead, buf, MAX_BUF_LEN); if(nReadLen <= 0) { printf("读取源文件出错!\n"); break; } nWriteLen = write(fdWrite, buf, nReadLen); if(-1 == nWriteLen) { printf("生成目标文件出错!\n"); return -5; } } return 0; }
原子操作:
ssize_t pread(int fd, void * buf, size_t len, off_t offset);
ssize_t pwrite(int fd, const void * buf, size_t len, off_t offset);