• 《Linux/Unix》系统编程第九章学习笔记


    I/O库函数

    I/O 数据库是一系列文件操作函数,既方便用户使用,又提高了整体效率。

    看起来比较优质的 I/O 库函数汇总,链接如下:https://blog.csdn.net/xiaxiaoyule/article/details/44050507?utm_source=app&app_version=4.15.0&code=app_1562916241&uLinkId=usr1mkqgl919blen

    一、I/O数据库与系统调用

    几乎每个支持C语言编程的操作系统都可以提供文件I/O库函数。

     

    二、I/O 库函数的算法

    (一)程序必须给每个文件声明一个指针变量,这个变量的类型为FILE*,当它处于活动状态时为流所用。

     

    (二)流通过fopen函数打开,打开的时候必须指定需要访问的文件或者设备以及访问方式。例如: FILE* fopen(const char* filename,const char*mode)

     

    (三)根据需要对文件进行读取和写入。

     

    (四)fread算法:

    fread算法如下:

    (1)在第一次调用 fread()时,FILE结构体的缓冲区是空的,fread()使用保存的文件描述符fd发出一个

    n=read(fd,fbuffer,BLKSIZE);

    系统调用,用数据块填充内部的 fbuf [] 的指针、计数器和状态变量,以表明内部缓冲区有一个数据块。

    尝试满足来自内部缓冲区的fread()调用。

    若,内部缓冲区没有足够的数据,则会再发出一个 read()系统调用来填充内部缓冲区,将数据从内部缓冲区传输到程序缓冲区,直到满足程序所需的字节数。将数据复制到程序缓冲区后,他会更新内部缓冲区的指针、计数器等,为下一个fread()做好准备。然后返回实际读取的数据对象;

    (2)在之后的每次fread()调用中,它都尝试满足来自FILE结构体内部缓冲区的调用。当缓冲区变成空时,它就会发出 read()系统调用来重新填充内部缓冲区。

    因此,fread()一方面接受来自用户程序的调用;另一方面向操作系统内核发出read()系统调用。除了系统调用之外,所有fread()处理都在用户模式映像中执行。它只在需要的时候才会进入操作系统内核,并且以一种最高效匹配文件的方式进入。会提供自动缓冲机制。

     

    (五)fwrite()算法

    fwrite()在每次被调用的时候,它将数据写入内部缓冲区,并调整缓冲区的指针、计数器和状态变量,以跟踪缓冲区的字节数。如果缓冲区已满,则发出write()系统调用,将整个缓冲区写入操作系统内核。

     

    ()fclose函数可以关闭文件流的局部缓冲区,然后,它会发出一个close(fd)系统调用来关闭 FILE 结构体中的文件描述。最后释放 FILE 结构体,并将 FILE 指针重置为NULL。

    例如: fclose(FILE* steam) ###### I/O函数列表:

     

    三、使用I/O库函数或系统调用

    ·fread() 和 fwrite() 将数据从内核复制到内部缓冲区,然后从内部缓冲区将数据复制到程序缓冲区。

    ·read()将数据直接复制到程序的缓冲区。

    所以,它传输了两次数据;

    而 read() 将数据从内核直接复制到程序的缓冲区,只复制了一次。因此对于BLKSIZE为单位的读/写数据来说read()比 fread()更高效,同样,write()比 fwrite()更高效。

    当然,以上的高效是相对于BLKSIZE为单位的读/写数据来说的。

     

    四、I/O库模式

    r+:表示读/写,不会阶段文件;

    w+:表示读/写,但是会先截断文件;若文件不存在,创建文件;

    a+:表示通过追加进行读/写,文件不存在创建文件。

     

    五、文件流缓冲

    • 无缓冲

    • 行缓冲

    • 全缓冲 通过fopen()创建文件流之后,在对其执行任何操作之前,用户均可发出一个 setvbuf(FILE *stream, char *buf, int node, int size) 调用来设置缓冲区(buf)、缓冲区大小(size)和缓冲方案(mode),它们必须是以下一个宏:

    • IONBUF:无缓冲

    • IOLBUF:行缓冲

    • IOFBUF:全缓冲 此外,还有其他的setbuf()函数,是setvbuf()的变体。对于行缓冲流或全缓冲流,可用fflush(stream)立即清除流的缓冲区。

    •  

     

  • 相关阅读:
    【mysql】八、mysql的学习---查询缓存
    【mysql】七、mysql的学习---应用优化
    【mysql】六、mysql的学习---SQL优化
    【mysql】五、mysql的学习---存储引擎
    【mysql】四、mysql的学习---触发器
    【mysql】三、mysql的学习---存储过程和函数
    【mysql】二、mysql的学习---视图
    server --SSD中,SATA,m2,PCIE和NVME各代表了什么,关系是什么
    windows--禁用驱动程序强制签名
    linux --kernel 和 OS 的关系区别
  • 原文地址:https://www.cnblogs.com/Aegon-Targaryen/p/15311528.html
Copyright © 2020-2023  润新知