Linux程序设计:文件I/O的概念、FILE结构体、文件描述符

目录

标准C的I/O

FILE结构体

标准C的IO缓存类型

行缓存案例

文件描述符

文件描述符与文件指针

标准文件指针

文件描述符与文件指针相互转换


标准C的I/O

char *fgets(char *s, int size, FILE *stream);
int printf(const char *format, ...);
int fprintf(FILE *stream, const char *format, ...);
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);

FILE结构体

typedef struct iobuf{
    int cnt; /*剩余的字节数*/
    char *ptr; /*下一个字符的位置*/
    char *base; /*缓冲区的位置*/
    int flag; /*文件访问模式*/
    int fd; /*文件描述符*/
}FILE;
char *base; /*缓冲区的位置*/
  • 库函数对内核函数文件操作封装的主要缘由和实现缓冲功能的主要体现
int fd; /*文件描述符*/ 
  • 实现文件操作的根本

标准C的IO缓存类型

全缓存
  • 要求填满整个缓存区后才进行I/O 系统调用操作。对于磁盘文件通常使用全缓存访问。
行缓存
  • 涉及一个终端时(例如标准输入和标准输出),使用行缓存。
  • 行缓存满自动输出
  • 碰到换行符自动输出
无缓存
  • 标准错误流stderr 通常是不带缓存区的,这使得错误信息能够尽快地显示出来。

行缓存案例

#include <stdio.h>
int main(void)
{
    printf("hello iotek");
    while(1){
        sleep(1);
    }
    return 0;
}
  •  printf("hello iotek"); 不加"\n"换行符,等程序结束自动输出。若加换行符,直接自动输出。

文件描述符

  • 对于内核而言,所有打开文件都由文件描述符引用
    • 文件描述符是一个非负整数
    • 打开一个现存文件创建一个新文件时,内核向进程返回一个文件描述符
    • 读、写一个文件时,用open或creat返回的文件描述符标识该文件,将其作为参数传送给read或write
  • 在POSIX应用程序中,整数0、1、2被替换成符号常数STDIN_FILENO、STDOUT_FILENO和STDERR_FILENO。这些常数都定义在头文件<unistd.h>中。
  • 文件描述符(这里所说的文件描述符实际是文件描述符标志)的范围0 --OPEN_MAX
    • 早期的UNIX版本采用的上限值是19 (允许每个进程打开20个文件)。
    • 现在很多系统则将其增加至63,Linux为102
  • 文件描述符除了文件描述符标志外,还包括一个文件表项的指针,所有的文件描述符组成一个文件描述符表,每个进程都有一个记录项,每个记录项都有一张打开的文件描述符表,而文件表项则是全局唯一的,所有的进程共用一张文件表。
  • 通过测试发现,不同程序打开不同的文件,文件描述符可以重复,可见文件描述符在不是所有进程共用的(0,1,2除外),不同进程存储自己私有的文件描述符

文件描述符与文件指针

标准文件指针

stdin 0 STDIN _FILENO
stdout 1 STDOUT_FILENO
stderr 2 STDERR_FILENO

文件描述符与文件指针相互转换

  • fdopen():文件描述符=>文件指针(fd=>FILE*)
FILE *fdopen(int fd, const char *mode);
  • fileno():文件指针=>文件描述符(FILE*=>fd)
int fileno(FILE *stream);

猜你喜欢

转载自blog.csdn.net/baidu_41388533/article/details/108392631