从I/O到文件格式

谈效率

unbuffered I/O(read write)

#include <unistd.h>
ssize_t read(int filedes, void *buf, size_t nbytes);
ssize_t write(int filedes, void *buf, size_t nbytes);
这里buf的大小严重影响效率,如果buf为1的话,比起最优大小可以差近50倍。当buf为4096个字节时效率最高(不一样的系统结果也不一样)。
这里的read和write都是直接调用内核的系统调用。(内核怎么做的先不理会了)

标准 I/O

#include <stdio.h>
// 标准io只写了读写字符的二进制的没写,主要是说效率差别。
// 一次读写一个字符的函数
int getc(FILE *fp);
int fgetc(FILE *fp);
int getchar(void);
int putc(int c, FILE *fp);
int fputc(int c, FILE *fp);
int putchar(int c);
// 一次读写一行字符的函数
char *fgets(char *restrict buf, int n, FILE *restrict fp);
char *fputs(const char *restrict str, FILE *restrict fp);
这里读写一个字符和一行字符的标准I/O效率差别不是很大,和直接试用write和read的最佳时间接近。
试用标准I/O其实无需考虑缓冲区的大小,知道缓冲区积累了合适的字符时才会进行系统调用真正的读写。

我的错误

就在几天前刚刚解决了的问题,今天突然又不知道啥原因了,我很郁闷。
是这样的,我打开一个文件写完后又读取,总是读不出来。之后我在写完后,关闭文件又打开再写,这样是成功的。
查了查中知道了,以前没这样随机读取过文件,没有这种意识:写完文件后,文件的偏移量,是在文件末尾的,只
有重新设置文件偏移量才可以。 fseek(fp, 0 , SEEK_SET);

自定制格式文件

如果文件很大的话,你很难去把文件的内容全部读入内存,通过这种偏移,你可以把文件分割成好多块,把各个块的偏移记录在文件开头固定长度内。
如果寻找某块的内容,把开头的固定一段读入内存,找到要读取目标的偏移和长度,就可以很容意单独的取出文件内容的一部分。 
灵活的东西,往往一开始都是写死的东西,比如,计算机启动时从硬盘固定的地址读取数据。所以不要指望他出生就很灵活。

write by fgd << "如有转载请注明出处cnblogs.com/wendao"

原文地址:https://www.cnblogs.com/wendao/p/2646124.html