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

posted @ 2021-09-19 20:33  20191310李烨龙  阅读(27)  评论(0编辑  收藏  举报