IO操作是我们程序运行的基础,数据在程序运行结束时需要保存就必须使用IO操作。IO主要包括两类:标准IO与系统IO
一 标准IO
标准IO是为了避免跨平台移植引起的不必要异常,指定的一系列标准函数,无论linux、windows都可以使用。
标准IO常用API包括:
fopen、fwrite、fread、fclose、prinf、fprintf、fget、fput
等均是以f开头。
其中:
fopen的mode
r/r+ 是不创建文件,前者只读,后者可读写、
w/w+ 能创建文件,并且把文件置空,前者只写,后者可读写
a/a+ 能创建文件,但不置空文件,在文件末尾写,前者只写,后者可读写
fputc、fgetc;逐个字节读写
fputs、fgets;定义缓冲区,缓冲区填满后操作。整行读取
fwrite、fread。以字节位计算长度,按照指定的长度和次数读取数据,遇到结尾或完成指定长度读取后停止。
通常标准IO伴随着FILE结构体。
二 系统调用IO
系统调用IO是标准IO的底层实现,通常受制于所存在的操作系统环境。
系统调用IO常用API包括:
open、close、read、write、lseek
系统调用IO通常伴随一个文件描述符,是个整型数。通常使用ulimit -n查看。文件描述符是文件指针在一个指针数组中的下标索引位置。该指针数组存在于当前进程的地址空间文件描述符优先使用当前范围最小的。
三 IO效率比较
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>
void fgetcAndFputc()
{
FILE *read, *write;
int ch;
read = fopen("b", "r");
write = fopen("c", "w+");
while(1) {
ch = fgetc(read);
if (ch == EOF) {
break;
}
fputc(ch, write);
}
fclose(write);
fclose(read);
return;
}
void fgetsAndFputs(int size)
{
int buff_size = size;
FILE *read, *write;
read = fopen("b", "r");
write = fopen("c", "w");
char *buf[buff_size];
const char *ch;
while(1) {
ch = fgets(buf, buff_size, read);
if(ch == NULL)
break;
fputs(buf, write);
}
fclose(write);
fclose(read);
puts("OK!");
exit(0);
}
void freadAndFwrite(int size)
{
int buff_size = size;
FILE *read, *write;
read = fopen("b", "r");
write = fopen("c", "w");
char *buf[buff_size];
const char *ch;
while(1) {
ch = fread(buf, 1, buff_size, read);
if(ch <= 0) //end of file
break;
fwrite(buf, 1, ch, write);
}
fclose(write);
fclose(read);
puts("OK!");
exit(0);
}
void removeLine(int line)
{
int fd1, fd2;
fd1 = open("test.c");
fd2 = open("test.c");
lseek(fd1, line, )
}
int main (int argc, char *argv[])
{
freadAndFwrite(atoi(argv[1]));
puts("OK!");
exit(0);
}
IO效率依赖于buffer_size大小。
实验结果如下,复制一个7030556行162MB大小的文件。
buffer_size | 1 | 8 | 1024 | 10240 |
time | 15.1 | 2.5 | 1.2 | 1.2 |
由此可见buffer_size并非是越大越好,当超过一定阈值时到达系统瓶颈,同样无法提高IO效率