基础IO 文件描述符

stdin & stdout & stderr

  1. C 会默认打开三个标准输入输出流,分别是stdin,stdout,stderr;对应的文件描述符是0,1,2;且分别对应的设备是键盘,显示器,显示器。
  2. 这三个流的数据类型是FILE*,fopen是返回值类型,文件指针。

open函数

基础IO 文件描述符_第1张图片

#include 
#include 
#include 

int open(const char *pathname, int flags);
int open (const char *pathname, int flags,mode_t mode);

pathname :要打开的文件或要创建的目标文件

flags:打开文件时,可以传入多个参数选项,用下面的一个或者多个“或”运算,构成flags

参数:

O_RDONLY:只读打开

O_WRONLY:只写打开

O_RDWR:读,写打开

以上三个常量必须存在一个并且有且只有一个

O_CREAT:若文件不存在,则创建它。需要使用mode选项,来指明新文件的访问权限。

O_APPEND:追加写

返回值:

成功:新打开的文件描述符

失败:-1

open函数具体使用哪个和具体的应用场景相关,如果目标文件不存在,需要open创建,则第三个参数表示创建文件的默认权限,否则,使用两个参数的open。

open函数返回值

1.fopen , fclose , **fread **, fwrite 都是C标准库中的函数,叫C库函数。

2.open,close, read, write ,lseek 都属于系统提供的接口,称为系统调用接口。

基础IO 文件描述符_第2张图片

通过上图可以发现库函数与系统调用接口是上下级的关系。可以认为,f#系列的函数是对系统调用的封装,方便二次开发。

文件描述符fd

文件描述符是一个小整数

基础IO 文件描述符_第3张图片

文件描述符是从0开始的小整数,当我们打开文件时,操作系统在内存中要创建相应的数据结构来描述目标文件。于是有了file结构体。表示一个已经打开的文件对象。

执行open系统调用,必须要让文件和进程相关联,每个进程都有一个指针*files,指向file_struct,该表最重要的部分就是包含一个指针数组,每个元素都是一个指向打开文件的指针,本质上文件描述符就是该数组的下标,根据文件描述符就可以找到对应的文件。

文件描述符实际上是操作系统对文件的管理。

文件描述符分配规则:从未被使用的最小的开始分配。

重定向的本质

假设关闭fd:1

#include 
#include 
#include 
#include 
#include 

int main()
{
    close(1);
    int fd=open("myfile",O_WRONLY|O_CREAT,00644);
    if(fd<0)
    {
        perror("open");
        return 1;
    }
    printf("fd:%d\n",fd);
    fflush(stdout);
    
    close(fd);
    exit(0);
}

通过代码我们发现,本来应该输出到显示器上的内容,写入到myfile中,其中,fd=1,这叫做输出重定向。

常见的重定向有:>,>>,<

基础IO 文件描述符_第4张图片

当数组的下标被关闭,open函数调用时默认打开最小未被使用的文件描述符对应的文件。

printf函数是C库中的输入输出函数,一般想stdout中输出,但当stdout访问文件的时候找出的还是fd:1,但此时下标为1表示的内容,已经变成了myfile的地址,不再是显示器文件的地址,所以所有的消息都输出到myfile文件中,进而完成输出重定向。

dup2的系统调用

#include 

int dup2(int oldfd, int newfd);

基础IO 文件描述符_第5张图片

dup2 函数中newfd是oldfd函数的一份拷贝,如果newfd打开先要关闭newfd,如果oldfd不是一个有效的文件描述符,那么调用失败,并且关闭newfd;如果oldfd是一个有效的文件描述符,且newfd等于oldfd,那么直接返回返回newfd。

你可能感兴趣的:(基础IO 文件描述符)