学习笔记2

2.markdown
第九章 I/O库函数
    9.1 I/O库函数
        I/O库函数是一系列文件操作函数,可以用来支持数据块的读和写,并且支持逻辑单元读和写,如行、字符、结构化记录
    9.2 I/O库函数与系统调用
    常用的系统调用函数:
        open()、read()、write()、lsweek()、close()
    常用的I/O库函数:
        fopen()、fread()、fwrite()、flsweek()、fclose()
    可以从相似度看出二者具有联系,I/O库函数依赖于系统调用函数,且一般情况下在该函数前加“f”即可,但是在语法上有些许细微的差别,主要看书上例题,同时程序之间也有一定的区别,需警记
    9.3 I/O库函数的算法
        9.3.1 fread算法
            (1)在第一次调用fread()时,FILE结构体的缓冲区是空的,fread()使用保存的文件描述符fd发出一个
                n=read(fd,fbuffer,BLKSIZE);
            发出的该指令用于系统调用,用数据块填充内部fbuf[]的同时,初始化它(包括指针、计数器和状态变量)。然后通过数据复制尝试完成fread()的调用。此时如果内部缓冲区没有足够数据,则再发一个系统调用函数read()来填充内部缓冲区,将数据传送到程序缓冲区,更新缓冲区的数据,为下个I/O库函数的调用请求做准备。
            (2)在随后的每次fread()调用中,它都尝试满足来自FILE结构体内部缓冲区的调用。除了read()系统调用之外,所有fread()处理都在用户模式映像中执行,且只在需要时才会进入操作系统内核,即内部缓冲区为空时。
        9.3.2 fwrite算法
            与fread算法相似,而传输方向不同。
        9.3.3 fclose算法
            当文件以写的方式被打开,fclose()会先关闭局部缓冲区,然后,它会发出一个close(fd)系统调用来关闭FILE结构体中的文件描述符。最后释放结构体,重置为NULL。
    9.4 使用I/O库函数或系统调用
        根据上面示例不难看出I/O库函数与系统调用有着很大的联系,可以说I/O库函数很大程度上依赖于系统调用函数。同时我们可以明显的看出在运行时间上系统调用函数要比I/O库函数更加快更加便利,因为一般情况下系统调用函数只复制一次数据,而I/O库函数需要二次运输(当内部缓冲区为空时)。但如果不是以BLKSIZE为单位进行读和写时,I/O库函数可能更加高效。
    9.5 I/O库模式
        每个模式字符串可包含一个+号,表示同司时读写,或者在写入
            "r+":表示读/写,不会截断文件。
            "w+":表示读/写,但是会先截断文件; 如果文件不存在,会创建文件。
            "a+":表示通过追加进行读/写;如果文件不存在,会创建文件。
        9.5.1 字符模式I/O
            int fgetc(FILE *fp);//fgetc()返回的是整数
            int ungetc(int c,FILE *fp);
            int fputc(int c,FILE *fp);
        9.5.2 行模式I/O
            char *fgets(char *buf,int size,FILE *fp):
                从fp中读取最多为一行(以\n结尾)的字符。
            int fputs(char *buf,FILE *fp):
                将buf中的一行写入fp中。
        9.5.3 格式化I/O
            格式化输入:(FMT=格式字符串)
            scanf(char *FMT,&items);
            fscanf(fp,char *FMT,&items);
            格式化输出:
            printf(char *FMT,items);
            fprintf(fp,char *FMT,items)
        9.5.4 内存中的转换函数
            sscanf(buf,FMT,&items);
            sprintf(buf,FMT,items);
            注:sscanf()和sprintf()并非I/0函数,而是内存中的数据转换函数。
        9.5.5 其他I/O库函数
            fseek()、ftell()、rewind():更改文件流中的读/写字节位置。
            feof()、ferr()、fileno():测试文件流状态。
            fdopen():用文件描述符打开文件流。
            freopen():以新名称重新打开现有的流。
            setbuf()、setvbuf():设置缓冲方案。
            popen():创建管道,复刻子进程来调用sh
        9.5.6 限制混合fread-fwrite
            当同时用于读和写时,会限制使用这二者的混合调用。
            每对fread()和fwrite()之间至少有一个fseek()或ftell()
    9.6 文件流缓冲
    每个文件流都有一个FILE结构体,其中包含一个内部缓冲区,进行读写时需要遍历内部缓冲区。分为三种情况:
        无缓冲:从非缓冲流中写入或读取的字符将尽快单独传输到文件或从文件中传输。
        行缓冲:遇到换行符时,写入行缓冲流的字符以块的形式传输。
        全缓冲:写入全缓冲流或从中读取的字符以块大小传输到文件或从文件传输。这是文件流的正常缓冲方案。
    通过fopen()创建文件流之后,在执行操作之前,用户可发一个
        setvbuf(FILE *stream,char *buf, int node, int size)
    来设置缓冲区(buf)、缓冲区大小(size)、缓冲方案(mode),它们必须是以下一个宏
        _IONBUF:无缓冲
        _IOLBUF:行缓冲
        _IOFBUF:全缓冲
    9.7 变参函数
        在I/O库函数中,printf()相当独特,不同类型的可变数量参数都可以调用它。(printf是块砖,哪里需要往哪里搬)
        关于参数声明后的参数调用和宏的用法见例题
一、文件操作有哪些:
    学习了第九章的内容,我知道了文件操作的两大类型便是读和写
    使用的相关函数为fread()和fwrite();在9.5 I/O库模式中也提到了关于文件操作的一些模式参数,除了笔记中记录到的“r+”、“w+”、“a+”以外,还有不加“+”的模式参数“r”代表读“w”代表写“a”代表追加,同时在网上查到“rb”为只读,“wb”为只写(此处二者打开的都是二进制文件)在这之后加入“+”便可同时读写
二、二进制文件和文本文件如何转换:
    在之前的学习中我们认识了ASCII字符,一定情况下可以用ASCII字符来进行二进制文件的文本转换,也就是一定程度上的文字转换,但当一篇文章或者一个文档全部是二进制的时候,就要用到第二章中所学的内容,使用vim修改,将其转化为十进制的文件,然后用ASCII字符进行转换(在第一眼看到问题时下意识以为ASCII码是16进制,然后查阅资料发现自己的漏洞,并进行更改)
三、数据结构如何读写
    关于这个问题,我认为如同之前所学数据结构一样,用抽象的东西去代替具体化的问题,也就是用抽象的问题去代替所谓的物理域,进而用所学的逻辑域的内容去解释物理域和抽象化的内容,最后通过逻辑代码指令将所要解决的问题具象化,让其可以呈现在计算机中,通过一系列的代码,让物理域出现在计算机上,转化为二进制代码进而实现目的
posted @ 2021-09-19 22:42  冯睿20191328  阅读(20)  评论(0编辑  收藏  举报