标准IO

[b]标准I/O[/b]的的操作则是围绕[b]stream[/b]进行的。

当用标准I/O库打开或创建一个文件时,我们已使一个流与一个文件相关联。
流的定向决定了所读、写的字符时单字节还是多字节。
只有两个函数可以改变流的定向
* 1、freopen函数清除一个流的定向
* 2、fwide函数设置流的定向

#include <stdio.h>
#include <wchar.h>

int fwide (FILE *fp, int mode);

返回值:若流时宽定向则返回正值,若是字节定向则返回负值。未定向则返回0;

当打开一个流时,标准I/O函数fopen返回一个指向FILE对象的指针。该对象通常是一个结构,它包含了标准I/O库为管理该流所需要的所有信息,包括:用于实际I/O的文件描述符、指向用于该流缓冲区的指针,缓冲区的长度、当前在缓冲区中的字符数以及出错标志等。
标准I/O提供缓冲的目的时尽可能减少使用read和write调用的次数。它也对每个I/O流自动地进行缓冲管理。
[b]STDIO提高了三种缓冲:[/b]
[b]1)全缓冲[/b]
在这种情况下,在填满IO缓冲区后才进行实际的IO操作。对于驻留在磁盘上的文件通常是由标准IO库实现全缓冲的。在一个流上执行第一次IO操作时,相关标准IO函数通常调用malloc获得所使用的缓冲区。
[b]2)行缓冲[/b]
在这种情况下,当在输入和输出中遇到换行符时,标准IO库执行IO操作,这允许我一次输入一个字符,但只有在写了一行之后才进行实际IO操作,当流涉及一个终端时候,通常使用行缓冲。
[b]3)不带缓冲[/b]
标准IO库不对字符进行缓冲存储。

IOS C要求下列缓冲特征。
[list]
[*] * 当且仅当标准输入和标准输出并不涉及交互式设备时,他们才是全缓冲。
[*] * 标准出错绝不会是全缓冲的
[*] * 标准出错是不带缓冲的
[*] * 如若是设计终端设备的其他流,则他们是行缓冲的,否则是全缓冲的。
[/list]
对任何一个给定的流,如果我们需要修改系统默认的情况,则可调用下列两个函数中的一个更改缓冲类型:

#include <stdio.h>

void setbuf(FILE *restrict fp, char *restrict buf);
int setvbuf(FILE *restrict fp, char *restrict buf, int mode, size_t size);


可以使用setbuf函数打开或关闭缓冲机制。
使用setvbuf,我们可以精确地指定所需的缓冲类型。

mode参数实现的:
[list]
[*]_IOFBF(full buffer)
[*]_IOLBF(line buffer)
[*]_IONBP(no buffer)
[/list]
任何时候,我们都可强制冲洗一个流。

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

打开流的三个函数

#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, const char *type);

返回值:若成功则返回文件指针,若出错则返回NULL。

区别:
[list]
[*]fopen打开一个指定的文件
[*]freopen在一个制定的流上打开一个指定的文件。
[*]fdopen获取一个现有的文件描述符(我们可能从open、dup、dup2、fcntl、pipe、socket、socketpair或accept函数得到此文件描述符),并使一个标准的IO流与该FD相结合。
[/list]
使用fclose关闭一个打开的流。

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

读和写流
以下三个函数可用于一次读一个字符。

#include <stdio.h>

int getc(FILE *fp);
int fgetc(FILE *fp);
int getchar(void);

返回值:若成功则返回下一个字符,若已到文件结尾或出错则返回EOF。
getchar等价于getc(STDIN)。

输出函数

#include <stdio.h>

int putc(int c, FILE *fd);
int fputc(int c, FILE *fd));
int putchar(int c);

putchar(c)等价于putc(c,STDOUT)
下面两个函数提供每次输入一行的功能

#include <stdio.h>

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

对应输出

#include <stdio.h>

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


[b]二进制IO
[/b]

#include <stdio.h>

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

返回值:读或者写的对象数目,即size_t nobj。

[b]格式化I/O
[/b]

#include <stdio.h>

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,….);

[list]
[*]
[*]printf将格式化的数据写到STDOUT
[*]fprintf写到制定的stream
[*]sprintf将格式化的字符送入数组buf中
[/list]

#include <stdio.h>

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,….)

[b]Implements:[/b]
每个STDIO流都有一个与其相关联的fd,可以对一个stream调用fileno函数获得fd。

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

如果要调用dup和fcntl等函数,则需要此函数。


[b]Others:
[/b]
sync、fsync、fdatasync函数
传统的UNXI实现在内核中设有高速缓冲区高速缓存或者页面高速缓存,大多数磁盘IO都通过缓冲进行。当将数据写入文件时,内核通常先将该数据复制到其中一个缓冲区中,如果该缓冲区尚未写满,则不将其排入输出队列,而是等待其写完或者当内核需要重用该缓冲区以便存放其他磁盘块数据时,再将该缓冲排入输出queue。然后待其到达队首时,才进行实际的io操作。这种输出方式被称为[b]延迟写[/b]。

延迟写减少了磁盘的读写次数,但是却降低了文件内容的更新速度,使得欲写到文件中的数据在一段时间内没有写到磁盘上。当系统发生故障时,这种延迟写可能造成文件更新内容的丢失。为了保证磁盘上实际文件系统与高速缓冲区高速缓存内容的一致性,UNIX提供了sync、fsync、fdatasync三个函数。

#include <stdio.h>

int fsync(int fieldes);
int fdatasysc(int fieldes);
void sync(void);

返回值:成功返回0,出错返回-1
[list]
[*]sync函数只是将所有修改过的块缓冲区排入写队列,然后就返回,它病不等待实际磁盘操作结束。
[*]通常被称为update的系统守护进程会周期性地调用sync函数这就保证顶起冲洗内核的块缓冲区。
[*]fsync函数只对由fd指定的单一文件起作用,并且等待起磁盘操作结束,然后返回。fsync可用于数据库这样的应用程序,这种应用程序需要确保修改的块立即写到磁盘上
[*]fdatasync函数类似fsync,但它只影响文件的数据部分,而除数据外,fsync还会同步更新文件的属性。
[/list]


参考资料:

http://en.wikipedia.org/wiki/C_file_input/output
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值