首页 > 其他 > 详细

标准I/O

时间:2019-06-17 22:53:03      阅读:161      评论:0      收藏:0      [点我收藏+]

  对于标准I/O都是围绕流进行操作,当用标准I/O库打开一个文件时,使一个流与一个文件相关联。

  流的定向决定了所读写的字符是单个字节还是多字节。当流创建时并没有定向,若在未定向的流上使用一个多字节I/O函数,则流设置为宽定向,若使用单字节函数,流定向为字节定向。

  FILE通常是一个结构,它包含了标准I/O库管理流所需的信息:用于实际I/O文件的描述符,指向流缓冲区的指针,缓冲区长度,当前缓冲区的字符数以及出错标志。

  标准IO流操作读写普通文件是使用全缓冲的,默认缓冲区长度是该文件系统优先选用的IO长度(从stat结构得到的st_blksize值)

缓冲

  1. 全缓冲(默认4096字节) :全缓冲指的是系统在填满标准IO缓冲区之后才进行实际的IO操作;注意,对于驻留在磁盘上的文件来说通常是由标准IO库实施全缓冲。
  2. 行缓冲 (默认1024字节):在这种情况下,标准IO在输入和输出中遇到换行符时执行IO操作,这允许我们一次输出一个字符,但是只有写了实际一行后才进行I/O操作;注意,当流涉及终端的时候,通常使用的是行缓冲。对于行缓冲有两个限制:一,因为标准I/O收集每一行缓冲区的长度是固定的,所以只要填满了缓冲区,那么即使还没有写入一个换行符,也进行I/O操作。二,任何时候只要通过标准I/O库从<a>一个不带缓冲的流(需要从内核读取数据),<b>一个行缓冲的流(它从内核请求需要的数据——数据可能在缓冲区中,不需要从内核读取)得到输入数据,那么就会冲洗所有行缓冲输出的流
  3. 无缓冲 :无缓冲指的是标准IO库不对字符进行缓冲存储;注意,标准出错流stderr通常是无缓冲的。

  冲洗:说明标准I/O缓冲区的写操作,缓冲区可能由标准I/O例程自动冲洗(当一个缓冲区满时)或者调用fflush冲洗一个流。在标准I/O方面,冲洗两层含义:1.将缓冲区中的内容写到磁盘上(缓冲区可能只是部分填满)2.驱动程序方面(tcflush)表示丢弃已存储在缓冲区中的内容。

  缓冲特征:

  • 标准输入和标准输出不指向交互式设备才指向全缓冲,指向交互设备是行缓冲
  • 标准错误绝不是全缓冲

  打开或关闭缓冲机制——这些函数一定要在流被打开后调用

#include <stdio.h>
void setbuf(FILE *restrict fp, char *restrict buf);
int setvbuf(FILE *restrict, char *restrict buf, int mode, size_t size);
//成功返回0,出错返回非0

  buff指向一个长度为BUFSIZ的缓冲区(定义在该头文件中),通常在此之后是全缓冲的,但是一个流如果与终端设备相关,某些设备也将其设置为行缓冲的,buf为NULL时关闭缓冲。

  如果buff为NULL,标准I/O库自动为其分配适当的缓冲区长度,改长度由BUFSIZ指定。从函数返回之前关闭该流,缓冲区的一部分用于存放他自己的管理操作信息,所以缓冲区存放的字节数实际少于size。一般情况下,系统选择分配缓冲区的长度,并自动分配缓冲区,在这种情况下,关闭此流时,标准I/O库自动释放缓冲区。

  setvbuf中的mode

  1. _IOFBF(满缓冲):当缓冲区为空时,从流读入数据。或者当缓冲区满时,向流写入数 据。
  2. _IOLBF(行缓冲):每次从流中读入一行数据或向流中写入一行数据。
  3. _IONBF(无缓冲):直接从流中读入数据或直接向流中写入数据,而没有缓冲区。

  强制冲洗缓冲

#include <stdio.h>
int fflush(FILE *fp);
//成功返回0出错返回非0

打开流

  除非流引用终端设备,否则按系统默认,流被打开是全缓冲的,若引用终端设备则是行缓冲。

#include <stdio.h>  
FILE* fopen(const char* restrict pathname, const char* restrict type);  
FILE* freopen(const char* restrict pathname, const char* restrict type, FILE* restrict fp);  
FILE* fdopen(int filedes, char* type); 

  fopen打开一个指定的文件。

  freopen在一直指定的流上打开一个指定的文件,如若该流已经打开,则先关闭该流。如果该流已经定向,则freopen清除该定向。此函数一般用于将一个指定的文件打开为一个预定的流:标准输入,标准输出或标准出错。fdopen获取一个现有的文件描述符,并使一个标准的IO流与该描述符相结合。此函数常用与由创建管道和网络通信函数返回的描述符,因为这些特殊类型的文件不能用标准IO fopen函数打开,所以我们必须先调用设备专用函数获取一个文件描述符,然后用fdopen使一个标准IO流与该描述符相关联。

type参数指定对IO流的读写方式,详细如下表(使用b,使得标准IO可以区分文本文件和二进制文件)

技术分享图片

  注意:对于fdopen,type的意义稍有不同,因为该描述符已经被打开,所以fdopen为写而打开并不截短该文件,另外也不能创建该文件。

对于读写类型打开一个文件时(图中的+)

  1. 如果中间没有fflush,fseek,fsetpos,frewind则在输出的后面不能直接跟输入
  2. 如果中间没有fseek,setpos,rewind或一个输入操作没有到达文件尾端,输入操作后不能跟输出

总结一下上表的内容:

技术分享图片

#include <stdio.h>
int fclose(FILE *fp);

  在该文件被关闭前,冲洗缓冲区中的输出数据,缓冲区中的任何数据被丢弃,如果标准I/O库自动为流分配了一个缓冲区,则释放此缓冲区。

  一个进程终止时(直接调用exit或从main中返回)所有带为写缓冲数据的标准I/O流都被冲洗,所有打开的I标准/O流都被关闭。

 

标准I/O

原文:https://www.cnblogs.com/tianzeng/p/11042511.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!