标准I/O的缓存

标准I/O的缓存

概述

    标准 I / O库,它们的操作则是围绕流( s t r e a m)进⾏的 。当⽤标准I / O库打开或创建⼀个⽂件时,我们已使⼀个流与⼀个⽂件相结合。

    当打开⼀个流时,标准 I / O函数f o p e n返回⼀个指向F I L E对象的指针。该对象通常是⼀个结构,它包含了I / O库为管理该流所需要的所有信息:⽤于实际 I / O的⽂件描述符,指向流缓存的指针,缓存的⻓度,当前在缓存中的字符数,出错标志等等。

FILE 相关的声明与定义

__BEGIN_NAMESPACE_STD宏定义

文件:/usr/include/sys/cdefs.h

…

/* The standardlibrary needs the functions from the ISO C90 standard

   in the std namespace.  At the same time we want to be safe for

   future changes and we include the ISO C99code in the non-standard namespace __c99. The C++ wrapper header take case of adding the   definitions to the global namespace.  */

#ifdefined __cplusplus && defined _GLIBCPP_USE_NAMESPACES

# define__BEGIN_NAMESPACE_STD  namespace std {

# define__END_NAMESPACE_STD    }

# define__USING_NAMESPACE_STD(name) using std::name;

# define__BEGIN_NAMESPACE_C99  namespace __c99 {

# define__END_NAMESPACE_C99    }

# define__USING_NAMESPACE_C99(name) using __c99::name;

#else

/* Forcompatibility we do not add the declarations into any

   namespace. They will end up in the global namespace which is what old codeexpects.  */

# define__BEGIN_NAMESPACE_STD

# define__END_NAMESPACE_STD

# define__USING_NAMESPACE_STD(name)

# define__BEGIN_NAMESPACE_C99

# define__END_NAMESPACE_C99

# define__USING_NAMESPACE_C99(name)

#endif

…


 

FILE声明

文件:/usr/include/stdio.h

/* Define outsideof namespace so the C++ is happy.  */

struct_IO_FILE;

__BEGIN_NAMESPACE_STD

/* The opaque typeof streams.  This is the definition usedelsewhere.  */

typedefstruct _IO_FILE FILE;

__END_NAMESPACE_STD

/* The opaque typeof streams.  This is the definition usedelsewhere.  */

typedef struct_IO_FILE __FILE;

#include<libio.h>

 

struct _IO_FILE 定义

struct _IO_FILE {

  int _flags;           /* High-order word is _IO_MAGIC;rest is flags. */

#define_IO_file_flags _flags

 

  /* The following pointers correspond to theC++ streambuf protocol. */

  /* Note: Tk uses the _IO_read_ptr and _IO_read_end fields directly. */

  char* _IO_read_ptr;   /* Current read pointer */

  char* _IO_read_end;   /* End of get area. */

  char* _IO_read_base;  /* Start of putback+get area. */

  char* _IO_write_base; /* Start of put area.*/

  char* _IO_write_ptr;  /* Current put pointer. */

  char* _IO_write_end;  /* End of put area. */

  char* _IO_buf_base;   /* Start of reserve area. */

  char* _IO_buf_end;    /* End of reserve area. */

  /* The following fields are used to supportbacking up and undo. */

  char *_IO_save_base; /* Pointer to start ofnon-current get area. */

  char *_IO_backup_base;  /* Pointer to first valid character of backuparea */

  char *_IO_save_end; /* Pointer to end ofnon-current get area. */

 

  struct _IO_marker *_markers;

 

  struct _IO_FILE *_chain;

 

  int _fileno;

#if 0

  int _blksize;

#else

  int _flags2;

#endif

  _IO_off_t _old_offset; /* This used to be_offset but it's too small.  */

 

#define__HAVE_COLUMN /* temporary */

  /* 1+column number of pbase(); 0 is unknown.*/

  unsigned short _cur_column;

  signed char _vtable_offset;

  char _shortbuf[1];

 

  /* char* _save_gptr;  char*_save_egptr; */

 

  _IO_lock_t *_lock;

#ifdef_IO_USE_OLD_IO_FILE

};


 

打印有关缓存状态信息

测试代码

#include<stdio.h>

 

void    pr_stdio(const char *, FILE *);

int             is_unbuffered(FILE *);

int             is_linebuffered(FILE *);

int             buffer_size(FILE *);

 

int main(void)

{

        FILE   *fp;

 

        fputs("enter anycharacter\n", stdout);

        if (getchar() == EOF)

                printf("getcharerror");

        fputs("one line to standarderror\n", stderr);

 

        pr_stdio("stdin",  stdin);

        pr_stdio("stdout", stdout);

        pr_stdio("stderr", stderr);

 

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

                printf("fopenerror");

        if (getc(fp) == EOF)

                printf("getc error");

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

        return 0;

}

 

void

pr_stdio(constchar *name, FILE *fp)

{

        printf("stream = %s, ",name);

        if (is_unbuffered(fp))

                printf("unbuffered");

        else if (is_linebuffered(fp))

                printf("linebuffered");

        else /* if neither of above */

                printf("fullybuffered");

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

}

 

int  is_unbuffered(FILE *fp)

{

        return(fp->_flags &_IO_UNBUFFERED);

}

 

int is_linebuffered(FILE*fp)

{

        return(fp->_flags &_IO_LINE_BUF);

}

 

int buffer_size(FILE*fp)

{

        return(fp->_IO_buf_end -fp->_IO_buf_base);

}

 

程序输出

enter anycharacter

1

one line tostandard error

stream = stdin,line buffered, buffer size = 1024

stream = stdout,line buffered, buffer size = 1024

stream = stderr,unbuffered, buffer size = 1

stream =/etc/passwd, fully buffered, buffer size = 4096

 

代码说明

    当标准输⼊、输出连⾄终端时,它们是⾏缓存的,⾏缓存的⻓度是1024字节。

    当将这两个流重新定向到普通⽂件时,它们就变成是全缓存的,其缓存⻓度是该⽂件系统优先选⽤的 I / O⻓度,该系统的全缓存长度是4096。可参看https://blog.csdn.net/xiangguiwang/article/details/79733769 。


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值