20191310李烨龙第九章读书笔记
第九章读书笔记
知识点归纳
 1、I/O库函数是一系列文件操作函数,,相比于系统调用,ta们能以适合应用程序的逻辑单元读/写文件。
 系统函数:
- 
open()
用于创建一个新的文件描述符 - 
read()
读取文件,从文件描述符 fildes 相关联的文件里读入 nbytes 个字节的数据,并把它们放到数据区 buffer 中 - 
write()
把缓冲区 buffer 的前 nbytes 个字节写入与文件描述符 fildes 关联的文件中 - 
lseek()
用于改变读写操作时的位置指针 - 
close()
终止文件描述符 fildes 与其对应文件之间的关联I/O函数:
 - 
fopen()
用于对文件和终端的输入输出 - 
fread()
从一个文件流里读取数据,数据从stream读到由ptr指定的数据缓冲区里面; fwirte(),从stream获取数据记录写到ptr中,返回值是成功写入的记录个数 - 
fseek()
在文件流里面为下一次读写指定位置 - 
fclose(),关闭指定的文流stream,使所有未写出的内容全部写出。
 
2、I/O库函数模式
		"r+":表示读/写,不会截断文件。
		"w+":表示读/写,但是会先截断文件;如果文件不存在,会创建文件。
		"a+":表示通过追加进行读/写;如果文件不存在,会创建文件。
3、文件流缓冲
 通过fopen()创建文件流之后,在对其执行任何操作之前,用户均可发出一个
setvbuf(FILE *stream, char *buf, int node, int size) 
		调用来设置缓冲区(buf)、缓冲区大小(size)和 缓冲方案(mode),它们必须是以下一个宏:
_IONBUF:无缓冲:从非缓冲流中写入(读取)的字符将尽快单独传输到文件(从文件传输)
_IOLBUF:行缓冲:遇到换行符,写入行缓冲流的字符以块的形式传输,如文件流stdout
_IOFBUF:全缓冲:文件流的正常缓冲方案,以块大小传出
问题与解决思路
实践内容
1、练习9.1 在如下程序中,通过一个系统调用来写每个字符是非常低效的。用一个write()系统调用来替换for循环。
原代码:
#include <fcntl.h>
int main(int argc, char *argv[]){
	int fd;
	int i, n;
	char buf[4096];
	if (argc < 2) exit(1);
	fd = open(argv[1], o_RDONLY);
	if (fd < 0) exit(2);
	while (n = read(fd, buf, 4096)){
		for (i = 0; i < n; i++){
			write(1, &buf[i], 1);
		}
	}	
}
编译中出现问题:

解决方法:
该问题是没有提供函数所需的库文件导致的,所以需要加上exit()和write()read()的库文件如下:
#include <stdlib.h>
#include <unistd.h>
参考Linux系统调用函数write()的用法,write()系统调用向指定的文件描述符内写入指定字节数的内容,函数原型为
ssize_t write(int fd, const void *buf, size_t count);
其中参数count表示最多写入的字节数,返回值表是真正写入的字节数。上述代码中将count设为1导致每次只能写入1bit,我们将其改为4096就可以免去循环的低效输出了,就如同系统调用read()一样。
更改之后的代码:
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[]){
	int fd;
	int i, n;
	char buf[4096];
	if (argc < 2) exit(1);
	fd = open(argv[1], o_RDONLY);
	if (fd < 0) exit(2);
	while (n = read(fd, buf, 4096)){
		write(1, &buf[i], 4096);
	}	
}
ma
                
            
        
浙公网安备 33010602011771号