文件流指针和文件标识符

文件流指针

文件流指针FILE是库中定义的一个结构体,该结构体包含文件名 文件状态和文件的当前信息 fd 文件描述符 FILE相当于对fd进行了封装

typedef struct _iobuf {
    int cnt;  // 剩余的字符,如果是输入缓冲区,那么就表示缓冲区中还有多少个字符未被读取
    char *ptr;  // 下一个要被读取的字符的地址
    char *base;  // 缓冲区基地址
    int flag;  // 读写状态标志位
    int fd;  // 文件描述符
    // 其他成员
} FILE;

当我们用printf 向标准输出 stdout输出时,想要输出的内容并没有直接输入到stdout(相当于一个文件)而是先将其放入到缓冲区中,当缓冲区存满了或用\n刷新缓冲区时,缓冲区中的内容才会被写入stdout

  • cnt 表示缓冲区中还有多少个字符未被读取
  • ptr 下一个要被读取的字符的地址
  • base 缓冲区基地址

假设缓冲区大小10字节,我们输入20字节的内容

首先向缓冲区中放入了10个字节大小的数据,FILE结构体中的 cnt 变为了10 ,说明此时缓冲区中有10个字节大小的数据可以读,同时我们假设缓冲区的基地址也就是 base 是0x00428e60 ,它是不变的 ,而此时 ptr 的值也为0x00428e60 ,表示从0x00428e60这个位置开始读取数据,当我们从缓冲区中读取5个数据的时候,cnt 变为了5 ,表示缓冲区还有5个数据可以读,ptr 则变为了0x0042e865表示下次应该从这个位置开始读取缓冲区中的数据 ,如果接下来我们再读取5个数据的时候,cnt 则变为了0 ,表示缓冲区中已经没有任何数据了,ptr 变为了0x0042869表示下次应该从这个位置开始从缓冲区中读取数据,但是此时缓冲区中已经没有任何数据了,所以要将输入流中的剩下的那10个数据放进来,这样缓冲区中又有了10个数据,此时 cnt 变为了10 ,注意了刚才我们讲到 ptr 的值是0x00428e69 ,而当缓冲区中重新放进来数据的时候这个 ptr 的值变为了0x00428e60 ,这是因为当缓冲区中没有任何数据的时候要将 ptr 这个值进行一下刷新,使其指向缓冲区的基地址也就是0x0042e860这个值!因为下次要从这个位置开始读取数据!

当我们从键盘输入字符串的时候需要敲一下回车键才能够将这个字符串送入到缓冲区中,那么敲入的这个回车键(\r)会被转换为一个换行符\n,这个换行符\n也会被存储在缓冲区中并且被当成一个字符来计算!比如我们在键盘上敲下了123456这个字符串,然后敲一下回车键(\r)将这个字符串送入了缓冲区中,那么此时缓冲区中的字节个数是7 ,而不是6。

缓冲区的刷新就是将指针 ptr 变为缓冲区的基地址 ,同时 cnt 的值变为0 ,因为缓冲区刷新后里面是没有数据的!

文件描述符

在Linux中,系统为了高效管理已经被打开的文件,用一个数组来记录打开的文件名,而文件描述符其实就是文件对应的数组下标。这样就用文件描述符和文件建立了练习。

标准输入输出说明

stdin,标准输入,默认设备是键盘,文件编号为0

stdout,标准输出,默认设备是显示器,文件编号为1,也可以重定向到文件

stderr,标准错误,默认设备是显示器,文件编号为2,也可以重定向到文件

重定向

int dup2(int oldfd,int newfd)
将文件描述符newfd所对应的文件改为oldfd所对应的文件 相当于修改后
newfd 和 oldfd表示的同一文件

如 dup2(fd,1)
让流如标准输出(1) 的文件流入 fd 文件

发布了89 篇原创文章 · 获赞 11 · 访问量 5305

猜你喜欢

转载自blog.csdn.net/weixin_44997886/article/details/104327873