标准I/O库

14 篇文章 0 订阅
1 篇文章 0 订阅

1.简介

标准I/O库控制比如缓冲分配和使I/O以最理想的大小操作,从而避免我们担心正确的缓冲大小。

2.流和文件对象

   当一个文件打开后,文件描述符被返回,而且文件描述符被用来I/O操作。标准I/O库,我们讨论流(streams)。
当我们用标准I/O库打开或者创建一个文件,我们就说文件已经和一个流关联了。

2.1流的定向(a stream's orientation)

  ASCII字符设置,一个单独的字节能够表示一个字符。但是国际字符设置,多于一个字节才能够表示一个字符。

标准I/O文件流能够设置为单字节流或者多字节(宽字节)流。一个流的定向决定了字符读写是单字节还是多字节。当一个流被创建的时候,它本身并没有定向。如果多字节I/O函数被用于一个没有定向的流,那么流被设置为宽定向。如果单字节I/O函数被用于一个没有定向的流,流被设置为单字节定向。一旦流的定向设置了,两个函数可以改变。freopen会清除流的定向;fwide函数能够用来设置流的定向。

2.2fwide函数

#include<stdio.h>
#include<wchar.h>
int wide<FILE *fp, int mode);
返回值:流宽定向返回正值,流字节定向返回负值,没有定向返回0.
fwide函数根据mode来直行不同操作:
1.如果mode是负值,fwide尝试设置流字节定向
2.如果mode是正值,fwide尝试设置流宽定向

3.如果mode是0,fwide不会设置定向,但是会返回值来区分流的定向。

⚠️:fwide不会更改已经设置定向的流的定向。  并且没有错误返回。

当我们打开一个流,标准I/O函数fopen返回一个指向FILE对象的指针。该对象是一个结构体,其中包括标准I/O库操作一个流需要的所有信息:实际I/O使用的文件描述,指向该流缓冲的指针,缓冲大小,当前缓冲字节数,错误标志等。

3.标准输入,标准输出,标准错误

三个流已经提前定义并且能够自动被进程使用:标准输入,标准输出和标准错误。
三个流指向同一个文件,文件描述符分别问STDIN_FILENO,STDOUT_FILENO,和STDERR_FILENO.
三个标准I/O流提前定义了指针为stdin,stdout和stderr。

4.缓冲

4.1缓冲类型

标准I/O库提供的缓冲目标是用最少read和write调用。并且,库还尝试自动处理缓冲,从而使得应用不去关心。
有三种类型的缓冲:
1.全缓冲:这种情况下,真实的I/O操作发生在标准I/O缓冲满了的时候。硬盘上的文件通常是全缓冲的。使用的缓冲通常被I/O标准函数malloc拿到,当I/O第一次在流上面操作时。
flush表示写标准I/O缓冲。缓冲能够自动更新到磁盘,当一个缓冲满了,或者我们调用fflush函数。
flush在unix系统上表示两种情况:对于标准I/O库,表示将缓冲更新到磁盘上面,也许该缓冲是不满的;对于中断设备,比如fcflush函数,表示忽略已经在缓冲里面的数据。
2.行缓冲:这种情况下,标准I/O库当一个新行字符在输入或者输出的时候操作I/O。该情况下允许我们一次输出一个字节。行缓冲通常用于中断设备--标准输入和标准输出。
行缓冲有两种情况:1.标准I/O库用来收取每行的缓冲大小已经确定,所以I/O在每行填满的情况下发生
              2.标准I/O库的输入是从无缓冲的的流或者行缓冲(数据从内核中获取)中获取,所有行缓冲输出流被操作。
3.无缓冲:标准I/O库不缓冲字节。如果我们有个fputs函数写15个字符。比如我们使用write函数,我们希望15个字符能够尽快输出。

标准错误流通常是无缓冲的,所以错误信息能够及时被打印出来,并不管是不是在同一行。

ISO C要求缓冲特点:
·标准输入和标准输出是全缓冲,当且仅当它们不表示交互设备时
·标准错误永远不能是全缓冲。
大多数应用默认如下:
·标准错误是无缓冲的
·所有的终端设备流是行缓冲的。不然是全缓冲的。

4.2setbuf,setvbuf函数

如果我们不喜欢默认的缓冲流,我们能够通过setbuf或者setvbuf函数修改它们。
#include<stdio.h>
void setbuf(FILE* restrict fp, char* restrict buf);
int setvbuf(FILE* restrict fp, char* restrict buf, int mode, size_t size);
返回值:成功返回0,失败返回非零。
setbuf函数能够设置有无缓冲。如果想要使用缓冲,buf必须指向BUFSIZ长度的buffer。通常,流被设置为全缓冲,但是一些系统会将涉及终端设备的流设置为行缓冲。设置为无缓冲,buf设置为NULL。


这两个函数调用发生在流打开之后,但是在任何操作操作该流之前。

4.3fflush函数

#include<stdio.h>
int fflush(FILE* fp);
返回值:成功返回0,失败返回EOF
fflush函数将流里面所有没有写的数据发送到内核。如果fp是NULL,所有的输出流都会更新。

5.打开流

fopen,freopen,fdopen函数用来打开标准I/O流。
#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 fd, const char* type);
返回值:成功返回文件指针,失败返回空指针。
三个函数的不同如下:
·fopen函数打开的是一个特定文件。
·freopen函数用一个特定流打开一个特定文件,如果流之前存在就先将其关闭。如果流之前有定向,先清除。该函数一般用来将文件以已定义的流(标准输入,标准输出,标准错误)打开。
·fdopen函数将一个已存在的文件描述符来绑定标准I/O流,文件描述符可能通过open,dup,dup2,fcntl,pipe,socket,socketpair,accept函数获取。该函数经常用来处理pipe或者网络产生的文件描述符。因为特殊类型的文件不能用标准I/Ofopen函数打开,我们不得不调用特殊设备函数来获取文件描述符,并使用fdopen函数将之与流绑定。
其中打开方式如下面表格


注意:新文件创建的type是w或者a,我们不能够设定文件的访问权限。访问权限的设置是通过S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH

关闭一个打开的流用fclose函数
#include<stdio.h>
int fclose(FILE* fp);
返回值:成功返回0,失败返回EOF。
所有的输出数据都会被更新写入在文件关闭之前。所有的输入数据都会被忽略。如果标准I/O库已经自动为流创建了缓冲,那么缓冲被释放掉。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值