大多数UNIX应用程序都使用I/O库,本章说明了该库所包含的所有函数,以及某些实现细节和效率方面的考虑。同时需要重点关注标准I/O使用了缓冲的技术,但同时也是因为它的出现,产生了很多细节上的问题.

流和FILE对象

unix系统调用的函数都是针对文件描述符操作的.而标准I/O库,它们的操作则是围绕流进行的。当用标准I/O库打开或创建一个文件时,使一个流与一个文件相关联.

关于流定向的问题,当一个流刚被创建时,它并没有定向,我们可以在未定向的流上使用一个多字节I/O函数或者单字节的函数.

#include <stdio.h>
#include <wchar.h> int fwide(FILE* fp,int mode);

当我们打开一个流时,标准I/O函数fopen返回的是一个指向FILE对象的指针.该对象是一个结构,它包含了:用于实际I/O的文件描述符、指向用于该流缓冲区的指针、缓冲区的长度、当前在缓冲区的字符数以及出错标志等。

  

缓冲

标准I/O库提供缓冲的目的是为了尽可能减少使用read和write调用的次数,它也对每个I/O流自动地进行缓冲管理,从而避免了应用程序需要考虑带来的麻烦.标准I/O提供了三种缓冲:

  • 全缓冲:在填满标准I/O缓冲区后才进行实际I/O操作.对于驻留在磁盘上的文件通常是全缓冲的.
  • 行缓冲:当在输入和输出中遇到换行符时,标准I/O库执行I/O操作.这允许我们一次输出一个字符,但只有在写额一行之后才进行实际I/O操作。当流涉及一个终端时(如标准输入和标准输出),通常使用行缓冲.
  • 不带缓冲:标准I/O库不对字符进行缓冲存储。通常标准出错流stderr是不带缓冲的.这就使得出错信息可以尽快显示出来.

对于任何一个给定的流,我们可以自己设定缓冲类型

void setbuf(FILE* fp,char* buf);
int setvbuf(FILE* fp,char* buf,int mode,size_t size);
//返回值:若成功则返回0,若出错则返回非0值

具体参数:setbuf函数

关闭缓冲:buf=NULL

setvbuf 具体参数:mode参数:_IOFBF 全缓冲  _IOLBF 行缓冲 _IONBF 不带缓冲

如果指定全缓冲或行缓冲,则buf和size可选择地指定一个缓冲区及其长度.

打开与关闭流:

#include <stdio.h>

FILE* fopen(const char* pathname,const char* type);//打开一个指定的文件
FILE* freopen(const char* pathname,const char* type,FILE* fp);//用于在一个指定的流上打开一个指定的文件.
FILE* fdopen(int filedes,const char* type);//获取一个现有的文件描述符,并使一个标准的IO流与该描述符相结合.
int fclose(FILE* fp);//关闭文件流

读写流:

一次一个字符的I/O.

#include <stdio.h>
int getc(FILE* fp);
int fgetc(FILE* fp);
int getchar(void);
//若成功则返回下一个字符,若已到达文件尾或出错则返回EOF /*******对应的输出函数***********/
int putc(int c,FILE* fp);
int fputc(int c,FILE* fp);
int putchar(int c);

一次一行字符的I/O

#include <stdio.h>

char* fgets(char* buf,int n,FILE* fp);
char* gets(char* buf);
//成功则返回buf,若已到达文件尾或者出错则返回NULL int fputs(const char* str,FILE* fp);
int puts(const char* str);
//若成功则返回非负值,若出错则返回EOF

注意点:

对于fgets,必须指定缓冲区的长度n,此函数一直读到下一个换行符为止,但是不超过n-1个字符,读入的字符被送入缓冲区.该缓冲区以null结尾。而gets是一个不安全的函数,它可能会造成缓冲区溢出.同时它与fgets的另一个区别是gets并不将换行符存入缓冲区中.

二进制I/O

#include <stdio.h>
size_t fread(void* ptr,size_t size,size_t obj,FILE* fp);
size_t fwrite(const void* ptr,size_t size,size_t obj,FILE* fp);
//读或写的对象数

通常用于读或写一个二进制数组或者用于读写一个结构体.

格式化I/O:

#include <stdio.h>

int printf(const char* format,...);
int fprintf(FILE* fp,const char* format,...);//若成功则返回输出的字节数,若输出出错则返回负值.
int sprintf(char* buf,const char* format,...);
int snprintf(char* buf,size_t n,const char* format,...);
//若成功则返回存入数组的字符数,若编码出错则返回负值. int scanf(const char* format,....);
int fscanf(FILE* fp,const char* format,...);
int sscanf(const char* buf,cpnst char* format,...);
//指定的输入项数;若输入出错或在任意变换前已到达文件尾则返回EOF.

定位流:

#include <stdio.h>

long ftell(FILE* fp);//若成功则返回当前文件位置指示,若出错则返回-1L.
int fseek(FILE* fp,long offset,int whence);//若成功则返回0,,若出错则返回非0值 void rewind(FILE* fp);

临时文件:

#include <stdio.h>

char* tmpnam(char* ptr);//指向唯一路径名的指针
FILE* tmpfile(void);//若成功则返回文件指针,若出错则返回NULL. char* tempnam(const char* directory,const char* prefix);//返回指向唯一路径名的指针.

示例:

#include <stdio.h>

char* tmpnam(char* ptr);//指向唯一路径名的指针
FILE* tmpfile(void);//若成功则返回文件指针,若出错则返回NULL. #include <stdio.h> int main(void){
char name[L_tmpnam],line[MAX_LINE];
FILE *fp; printf("%s\n",tmpnam(NULL));//first tmp name tmpnam(name);
printf("%s\n",name); if((fp=tmpfile())==NULL){
printf("tmpfile error");
exit(-);
} fputs("one line of output\n",fp);
rewind(fp); if(fgets(line,MAX_LINE,fp)==NULL){
printf("fgets error\n");
exit(-);
} fputs(line,stdout);
exit();
}

《APUE》-第五章标准IO库的更多相关文章

  1. C++ Primer 读书笔记: 第8章 标准IO库

    第8章 标准IO库 8.1 面向对象的标准库 1. IO类型在三个独立的头文件中定义:iostream定义读写控制窗口的类型,fstream定义读写已命名文件的类型,而sstream所定义的类型则用于 ...

  2. 《C++ Primer 4th》读书笔记 第8章-标准IO库

    原创文章,转载请注明出处:http://www.cnblogs.com/DayByDay/p/3936457.html

  3. c++ primer 学习杂记3【标准IO库】

    第8章 标准IO库 发现书中一个错误,中文版p248 流状态的查询和控制,举了一个代码例子: int ival; // read cin and test only for EOF; loop is ...

  4. [APUE]标准IO库(下)

    一.标准IO的效率 对比以下四个程序的用户CPU.系统CPU与时钟时间对比 程序1:系统IO 程序2:标准IO getc版本 程序3:标准IO fgets版本 结果: [注:该表截取自APUE,上表中 ...

  5. [APUE]标准IO库(上)

    一.流和FILE对象 系统IO都是针对文件描述符,当打开一个文件时,即返回一个文件描述符,然后用该文件描述符来进行下面的操作,而对于标准IO库,它们的操作则是围绕流(stream)进行的. 当打开一个 ...

  6. C5 标准IO库:APUE 笔记

    C5 :标准IO库 在第三章中,所有IO函数都是围绕文件描述符展开,文件描述符用于后续IO操作.由于文件描述符相关的操作是不带缓冲的IO,需要操作者本人指定缓冲区分配.IO长度等,对设备环境要求一定的 ...

  7. 文件IO函数和标准IO库的区别

    摘自 http://blog.chinaunix.net/uid-26565142-id-3051729.html 1,文件IO函数,在Unix中,有如下5个:open,read,write,lsee ...

  8. 高级UNIX环境编程5 标准IO库

    标准IO库都围绕流进进行的 <stdio.h><wchar.h> memccpy 一般用汇编写的 ftell/fseek/ftello/fseeko/fgetpos/fsetp ...

  9. 18、标准IO库详解及实例

    标准IO库是由Dennis Ritchie于1975年左右编写的,它是Mike Lestbain写的可移植IO库的主要修改版本,2010年以后, 标准IO库几乎没有进行什么修改.标准IO库处理了很多细 ...

随机推荐

  1. 使用PHP解压文件Unzip

    这是一个非常方便的PHP函数从.zip文件解压缩文件.它有两个参数:第一个是压缩文件的路径和第二 function unzip_file($file, $destination) { // creat ...

  2. CSS XHTML规范化命名参考

    CSS命名规则 头:header 内容:content/containe 尾:footer 导航:nav 侧栏:sidebar 栏目:column 页面外围控制整体布局宽度:wrapper 左右中:l ...

  3. 【好程序员笔记分享】——UIView与CALayer详解

    -iOS培训,iOS学习-------型技术博客.期待与您交流!------------ UIView与CALayer详解 研究Core Animation已经有段时间了,关于Core Animati ...

  4. ASIHTTPRequest中的DELETE、PUT、GET、POST请求实例-备用

    感谢分享 //  ASIFormDataRequestTests.m //  Part of ASIHTTPRequest -> http://allseeing-i.com/ASIHTTPRe ...

  5. 如何解决Bluetooth系统设计的棘手问题

    我们若想设计一套完善的蓝牙 (Bluetooth) 系统,就必须充分掌握其中的技术知识,例如协议堆栈.射频设计及系统集成等方面的专门知识.LMX9820 芯片的面世令蓝牙系统的设计工作变得更为容易.以 ...

  6. 【转】android 5.0 64bit系统加载库文件失败问题浅析

    原文网址:http://blog.csdn.net/andrewblog/article/details/43601303 最近公司的一个项目使用android 5.0 64 bit平台,相对以前版本 ...

  7. usaco5.5-Hidden Passwords

    最小表示法,感觉可以做成个模板,第一次RE是因为字符串长度变2倍了而我把数组开小了 Executing...   Test 1: TEST OK [0.008 secs, 3760 KB]   Tes ...

  8. usaco5.5-Picture

    离散化计算重叠矩形的周长. 称平行于x轴的边为横边,我们以横边为例,某一矩形中y坐标比较小的横边我们称为始边,另一边我们称为终边.用一条扫描线从下往上扫描,当扫到一条始边的时候,如果这条始边的正下方出 ...

  9. Abstract Methods and Classes

    阅读了Java的官方Doc,在此总结如下. Abstract Class & Method In jave, "abstract" can be a modifier to ...

  10. HTTP请求的TCP瓶颈分析

    这篇文章基本是对<Web性能权威指南>第一章和第二章的读书笔记,另外加一些扩展内容,这本书确实赞,推荐 针对三次握手.流量控制(接收窗口).慢启动(cwnd,拥塞窗口).队首阻塞等方面看下 ...