问题背景
在日常的工作中,经常会需要使用fprint、fwrite之类的函数写文件。
当需要写或读的数据量较大时,使用操作系统默认的策略可能就不够高效。
通常的做法就是使用自定义的缓冲区减少I/O操作。下面分二进制文件和文本文件的读写进行说明。
1.读写二进制文件
#define BUF_SIZE 4*1024*1024 //4M
unsigned char *ptr; //用于对缓冲区进行操作
unsigned char *buf; //声明buf
FILE *fin; //读取的文件
unsigned int x;
char c;
buf = (unsigned char *)malloc(BUF_SIZE);
ptr = buf; //使用ptr对buf进行操作
if(!buf){
printf("malloc buffer failed!\n");
return 0;
}
//读文件
if((fin = fopen(filename, "r+")) == NULL){
printf("Open file error!\n");
return 0;
}
read_cnt = fread(buf, 1, BUF_SIZE, fin); //从fin文件中一次性读取4M数据
//使用ptr对数据进行操作
x = (unsigned int)( *(unsigned int*)ptr ); //先进行指针的类型转换,然后取值,最后保险起见再进行类型转换。
c = (char)( *(char *)ptr);
//用完后,记得释放
free(buf);
close(fin);
以上就是使用自定义的缓冲区对二进制读写提速的方法。
需要注意的是,读写buf时,需要有一个计数便于判断buf的数据是否已读完或已写满。必要时需要重新将ptr指向buf的首地址,然后使用memset对缓冲区清零。
2.读写文本文件
读写文本文件由于fscanf和fprintf的对于格式的处理已经很便捷,只需重新设定读写文件时用到的buf大小提速即可。
查到了setbuf这个函数,整合我意。:)
setbuf:设置文件流的缓冲区
头文件:#include
函数定义:void setbuf(FILE stream, char buf)
FILE *fin = fopen(filename, "w+");
//直接使用字符数组开缓冲区也是一种方法,因为这种情景下,缓冲区的大小一般都是编码人员自己指定的,无需改动。
char buf[1024];
setbuf(fin, buf); //使用buf作为fin文件流的缓冲区域
fprintf(fin, "write some data\n");
//如果写入的数据不够1024,则只有fflush后才会有数据写到磁盘文件中
//如果之前有写满缓冲区,会自动写回磁盘文件。清空buf后继续使用
fflush(f);
fclose(f);