Skip to content

Latest commit

 

History

History
58 lines (44 loc) · 2.37 KB

10.8.md

File metadata and controls

58 lines (44 loc) · 2.37 KB

10.8 标准I/O

标准I/O库函数

ANSI C 定义了一组标准输入输出函数,在libc库中

  • fopen
  • fclose
  • fread
  • fwrite
  • fgets
  • fputs
  • scanf
  • printf 等等

上面的函数,应该都很熟悉,就不再多做介绍

FILE的流

标准I/O库是将一个打开的文件模型化为一个流,这个流其实就是一个指向FILE类型的结构 的指针,在程序开始之后,都会有三个打开的流对应标准输入,标准输出,标准错误

    #include <stdio.h>   //文件描述符
    extern FILE *stdin;    0
    extern FILE *stdout;   1
    extern FILE *stdrr;    2

FILE的流其中包括了文件描述符和缓冲区,对应的文件描述符如下:

    /* Standard file descriptors. */
    #define STDIN_FILENO 0 /* Standard input. */
    #define STDOUT_FILENO 1 /* Standard output. */
    #define STDERR_FILENO 2 /* Standard error output. */

而缓冲区,则和前面介绍的RIO是一样的目的,

I/O缓冲区

在linux下,如果你使用系统调用和标准I/O库函数来实现同样的功能,你会发现 系统调用的性能比库函数要低得多,这是因为系统调用时,Linux必须从运行用户 代码切换执行内核代码,然后再返回到用户代码,频繁系统调用会影响系统的性 能,而标准I/O函数使用缓冲区来避免过多的系统调用

例子:
用户程序使用fgetc函数时,fgetc会在打开的文件分配一个缓冲区来加速读写, 在用户第一次调用时,通过系统调用进入内核填满缓冲区,然后后面的fgetc调用 返回的数据会在缓冲区中得到,如果缓冲区被清空,再继续系统调用填满,这样 在用户空间读取数据比在内核读数据块得多,所以性能要好一些。

C标准库的I/O缓冲区

C标准库的I/O缓冲区有三种类型:

  • 全缓冲 如果缓冲区写满了就写回内核。常规文件通常是全缓冲的
  • 行缓冲 如果用户程序写的数据中有换行符就把这一行写回内核,或者如果缓冲区写满了就写回内核。标准输入和标准输出对应终端设备时通常是行缓冲的
  • 无缓冲 用户程序每次调库函数做写操作都要通过系统调用写回内核。标准错误输出通常是无缓冲的,这样用户程序产生的错误信息可以尽快输出到设备