linux编程主题之标准I/O与高级I/O

  对于标准I/O库,它们的操作是围绕流进行的。当用标准I/O库打开或创建一个文件时,我们已使一个流与一个文件相关联。

  对一个进程预定义了三个流,并且这三个流可以自动地被进程使用,它们是:标准输入、标准输出和标准出错,对应的文件指针分别为stdin、stdout和stderr。

  为了减少使用read和write的调用的次数,标准I/O库提供了三种类型的缓冲机制,分别为全缓冲、行缓冲和不带缓冲。

    全缓冲:在填满标准I/O缓冲区后才进行实际I/O操作。

    行缓冲:当在输入和输出中遇到换行符时,标准I/O库执行I/O操作。

    不带缓冲:标准I/O库不对字符进行缓冲存储。

  一般来说,标准出错是不带缓冲的,打开至终端设备的流是行缓冲的,其他所有流则是全缓冲的。这里要注意一点的是,全缓冲、行缓冲和不带缓冲只与流有关,要看流带不带缓冲,带怎样的缓冲,而与使用哪个标准I/O库中的函数无关。例如,不能认为使用了fgets函数就认为是行缓冲的。

  1、打开流的函数

       FILE *fopen(const char *restrict pathname, const char *restrict type);

  2、判断出错或到达文件尾端的函数

       int ferror(FILE *fp);

       int feof(FILE *fp);

  3、一次读一个字符的函数

       int fgetc(FILE *fp);

  4、一次写一个字符的函数

       int fputc(int c, FILE *fp);

  5、一次读一行的函数

       char *fgets(char *restrict buf, int n, FILE *restrict fp);

  6、一次写一行的函数

       int fputs(const char *restrict str, FILE *restrict fp);

  7、二进制I/O函数

      size_t fread(void *restrict ptr, size_t size, size_t nobj, FILE *restrict fp);

      size_t fwrite(const void *restrict ptr, size_t size, size_t nobj, FILE *restrict fp);

      其中,size指定每个元素的长度,如sizeof(float)等。nobj指定要写的元素的个数。

  8、定位流的函数

      long ftell(FILE *fp);

      int fseek(FILE *fp, long offset, int whence);

      void rewind(FILE *fp);

      int fgetpos(FILE *restrict fp, fpos_t *restrict pos);

      int fsetpos(FILE *fp, const fpos_t *pos);

  9、格式化I/O函数

      int printf(const char *restrict format, ...);

      int fprintf(FILE *restrict fp, const char *restrict format, ...);

      int sprintf(char *restrict buf, const char *restrict format, ...);

      int snprintf(char *restrict buf, size_t n, const char *restrict format, ...);

      int scanf(const char *restrict format, ...);

      int fscanf(FILE *restrict fp, const char *restrict format, ...);

      int sscanf(const char *restrict buf, const char *restrict format, ...);

  10、流与文件描述符

      int fileno(FILE *fp);

  高级I/O里面一项重要的技术是使用I/O多路转接。先构造一张有关描述符的列表,然后调用一个函数,知道这些描述符中的一个已准备好进行I/O时,该函数才返回。

  1、select函数

      int select(int maxfdp1, fd_set *restrict readfds, fd_set *restrict writefds, fd_set *restrict exceptfds, struct timeval *restrict tvptr);

  2、操作描述符集的函数

      int FD_ISSET(int fd, fd_set *fdset);

      void FD_CLR(int fd, fd_set *fdset);

      void FD_SET(int fd, fd_set *fdset);

      void FD_ZERO(fd_set *fdset);

     注意,声明了一个描述符集后,必须用FD_ZERO清除其所有位,然后在其中设置我们关心的各个位。

  3、poll函数

      int poll(struct pollfd fdarray[], nfds_t nfds, int timeout);

      其中struct pollfd{

                  int fd;

                 short events;

                 short revents;

             };

     events表示描述符关心什么事件,revents表示描述符发生了什么事件。其中比较重要的三个值是POLLRDNORM、POLLWRNORM、POLLERR。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值