UNIX标准IO

来源:互联网 发布:你不知道的js pdf 编辑:程序博客网 时间:2024/05/16 09:00
5 – 标准I/O库
  本章描述I/O库 : 标准I/O库处理很多细节 : 如缓冲区分配 ,以优化块长度执行I/O等 .
               这些处理使用户不必担心如何选择正确的块长度 ,但不深入理解I/O库函数的操作 ,也会带来一些问题 . 
  
  流和FILE对象 : 所有 [I/O函数] 都是围绕 [文件描述符] 的 ,当打开一个文件时 ,即返回一个文件描述符 ,然后该文件描述符就用于后续的I/O操作 .
  而对于 [标准I/O库] ,它们的操作是围绕 [流] 进行的,当用标准I/O库打开或创建一个文件时,我们已使用一个流与文件相关联.


  流的定向 : 决定了所读写的字符是单字节还是多字节的 .当一个流最初被创建时 ,它并没有定向 . 
             freopen函数 ,清除一个流的定向 ;
             fwide函数可用于设置流的定向 ;




标准I/O函数fopen返回一个纸箱 FILE对象的指针 ,该对象通常是一个结构 ,它包含了标准I/O库为管理该流需要的所有信息 ,
包括用于实际I/O的 :文件描述符 :指向该流缓冲区的指针 :缓冲区长度 :当前在缓冲区中的字节数 :及出错标志等 .




对一个进程预定义了3个流 ,并且这三个流可以自动的被进程使用 ,它们是是 :标准输入 ,输出 ,错误 .
引用的文件描述符即 :STDIN_FILENO : STDOUT_FILENO : STDERR_FILENO.
这三个标准流通过预定义指针 : stdin,stdout,stderr 引用包含在<stdio.h>中。




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




标准I/O提供了三种类型的缓冲:
1.全缓冲 : 在填满标准I/O缓冲区后才进行实际I/O操作 .
2.行缓冲 : 当在输入和输出遇到换行符时 ,标准I/O库执行I/O操作 ( 当涉及到一个终端时通常使用行缓冲 ).
3.不带缓冲 : 标准I/O库不对字符进行缓冲存储。




5.5打开流 : fopen , freopen , fdopen .
5.6读和写流 : getc  fgetc , getchar.
5.7每次一行I/O  fgets  gets
5.8标准I/O效率

5.10定位流




例程 :

/*******************************************************
*对三个标准IO打印缓冲信息
********************************************************/




#include <apue.h>
#include <myerr.h>


/********************************************************
*
*FILE 结构体
*
struct _iobuf { 
char *_ptr; //文件输入的下一个位置 
int _cnt; //当前缓冲区的相对位置 
char *_base; //指基础位置(应该是文件的其始位置) 
int _flag; //文件标志 
int _file; //文件的有效性验证 
int _charbuf; //检查缓冲区状况,如果无缓冲区则不读取 
int _bufsiz; //文件的大小 
char *_tmpfname; //临时文件名 
}; 
typedef struct _iobuf FILE;
*********************************************************/


void pr_stdio(const char *,FILE *);
int is_unbufed(FILE *); //不带缓冲
int is_linebufed(FILE *); //行缓冲
int buf_size(FILE *); //全缓冲








int main()
{
FILE *fp;

fputs("Enter Any Character\n",stdout);
if(getchar()==EOF) err_sys("getchar error");

fputs("One Line to STDERR\n",stderr);

pr_stdio("stdin",stdin);

pr_stdio("stdout",stdout);

pr_stdio("stderr",stderr);


if((fp=fopen("/etc/passwd","r"))==NULL) err_sys("fopen error");

if(getc(fp)==EOF) err_sys("getc error");

pr_stdio("/etc/passwd", fp);


return 0;
}


/*************************************************
,打印缓冲信息


标准IO 都是行缓冲 bufsize = 1024  
1024 是缓冲区长度 ,并不是讲输入输出行 限制为 1024 字节
每1024字节 系统调用一次write 。


标准错误 是 不带缓冲 bufsize = 1


普通文件 全缓冲     其缓冲长度是该文件系统优先选用的IO长度
(从stat结构中 得到 st_blksize 值) (此处4096)
*************************************************/


void pr_stdio(const char * name,FILE * fp)
{
printf("stream =%s, ", name);

if(is_unbufed(fp)) printf("unbufed\n");

else if(is_linebufed(fp)) printf("line buffered\n");

else printf("fully buffererd\n");

//printf(", buffer size =%d\n",buffer_size(fp));

}


int is_unbufed(FILE * fp)
{
return (fp->_flags & _IO_UNBUFFERED);
}


int is_linebufed(FILE *fp)
{
return (fp->_flags & _IO_LINE_BUF);
}


/*
int buf_size(FILE *fp)
{
return (fp->_bf._size);
}
*/









0 0