标准IO_打开和关闭文件_fopen,fdopen,freopen,stdin,stdout,stderr

目录

1.打开文件

1.1 fopen函数原型

1.1.1 fopen函数

1.1.2 fopen函数原理

1.1.3 文本文件和二进制文件区别?

1.1.4 “r"模式和“rb”模式区别?

1.1.5 fopen函数使用示例

1.2 fdopen函数原型

1.2.1 fdopen函数

1.2.2 fdopen函数原理

扫描二维码关注公众号,回复: 16765133 查看本文章

1.2.3 fdopen函数使用示例

1.3 freopen函数原型

1.3.1 freopen函数

1.3.2 freopen函数原理

1.3.3 freopen函数使用示例

2.关闭文件

2.1 fclose函数原型

2.1.1 fclose函数

3.stdin,stdout,stderr介绍


1.打开文件

1.1 fopen函数原型

1.1.1 fopen函数

#include <stdio.h>

FILE *fopen(const char *pathname, const char *mode);

函数简介:fopen函数是 C 语言标准库中的一个函数,用于打开文件并返回一个文件指针。

函数参数:

pathname:字符串,表示要打开的文件名。

mode:字符串,表示打开文件的模式,具体设置方法参考表 1-1

 表 1-1 fopen函数 mode参数参考表

函数返回值:

成功:返回文件指针。

失败:返回NULL,并设置errno。

1.1.2 fopen函数原理

图 1-1 fopen函数原理

调用fopen函数后,会在用户空间创建一个FILE对象,同时通过open系统调用在内核创建sturct file对象和struct inode对象,open系统调用原理参考:文件IO_打开和关闭文件(附Linux-5.15.10内核源码分析)

调用open成功后会返回一个fd(文件描述符),FILE对象的_fileno成员会记录该fd,_fileno是用户空间和内核空间数据交互的桥梁。

后续可以使用_fileno和文件IO系统调用直接和内核交互,也可以通过FILE文件指针和标准IO接口和内核交互。

1.1.3 文本文件和二进制文件区别?

图 1-2 文本文件和二进制文件

文本文件和二进制文件在存储层是一样的,都是以二进制形式存储。

不同的点在与逻辑层,文本文件通常为符合某种编码规范(如ASCII码)的文件,操作文本文件时,我们的输入输出数据要符合编码规范,这个是人为规定,如果不符合编码规范会出现乱码等现象。

二进制文件以值编码为规范,输入输出数据为数值(如十六进制)形式,以二进制模式读写文件,通常不容易出错,因为数据所见即所得,中间不存在转换环节。

1.1.4 “r"模式和“rb”模式区别?

、"r" 模式:以文本模式打开文件进行读取。在文本模式下,文件中的换行符会被转换为换行符(\n),而不同操作系统上的换行符可能有所不同(例如,Windows 上的换行符是 \r\n)。此模式适用于读取文本文件,例如纯文本文件、CSV 文件等。

"rb" 模式:以二进制模式打开文件进行读取。在二进制模式下,文件中的数据会以字节的形式读取,不会进行任何转换。此模式适用于读取二进制文件,例如图片、音频、视频等。

1.1.5 fopen函数使用示例

#define TEST_FILE "/tmp/test.txt"

int fopen_test() {
    FILE *fp = fopen(TEST_FILE, "r+");
    if (!fp) {
        perror("fopen error");
        return -1;
    }

    fclose(fp);
    return 0;
}

1.2 fdopen函数原型

1.2.1 fdopen函数

#include <stdio.h>

FILE *fdopen(int fd, const char *mode);

函数简介:fdopen函数是C语言中用于将文件描述符(file descriptor)转换为文件指针(FILE*)的标准库函数之一。

函数参数:

fd:整数,表示要转换的文件描述符。

mode:参考fopen函数mode参数。

函数返回值:

成功:返回文件指针。

失败:返回NULL,并设置errno。

1.2.2 fdopen函数原理

图 1-3 fdopen函数原理

从fopen函数原理我们知道,用户空间和内核空间要交互数据又两种方法:

  • 通过_fileno和文件IO系统调用直接和内核交互。
  • 通过FILE文件指针和标准IO接口和内核交互。

fdopen函数主要作用为已通过open函数开的文件描述符再打开一个FILE文件指针,从而可以通过FILE文件指针和标准IO接口和内核交互。

1.2.3 fdopen函数使用示例

int fdopen_test() {
    FILE *fp = fdopen(1, "w");
    if (!fp) {
        perror("freopen error");
        return -1;
    }

#define TEST_STRING "helloworld\n"
    fwrite(TEST_STRING, strlen(TEST_STRING), 1, fp);

    printf("let`s go\n");
    fclose(fp);
    return 0;
}

1.3 freopen函数原型

1.3.1 freopen函数

#include <stdio.h>

FILE *freopen(const char *pathname, const char *mode, FILE *stream);

函数简介:freopen函数是C语言中用于重新定向文件流的标准库函数之一。

函数参数:

pathname:字符串,表示要重新定向到的文件名。

mode:参考fopen函数mode参数。

stream:已打开的文件流指针,表示要重新定向的文件流。

函数返回值:

成功:返回文件指针。

失败:返回NULL,并设置errno。

1.3.2 freopen函数原理

 图 1-4 freopen函数原理1

  图 1-5 freopen函数原理2

freopen函数主要用来做文件重定向。

调用freopen函数之前,我们已经通过fopen函数打开了一个文件并返回FILE文件指针,也可以是默认打开的文件指针如:stdin,stdout,stderr。已打开的文件会在内核创建struct file和struct inode对象。

当调用freopen函数后,原先的FILE文件指针对应的内核struct file和struct inode会被新的struct file对象和struct inode对象替换,原先的对象会被关闭,此时我们操作FILE文件指针,我们操作的是新的struct file对象和struct inode对象。

freopen内部其实是通过dup3系统调用实现,dup3系统调用原理请参考:文件IO_复制文件描述符(附Linux-5.15.10内核源码分析)

1.3.3 freopen函数使用示例

int freopen_test() {
    FILE *fp = freopen("test.log",  "w", stdout);
    if (!fp) {
        perr string-literal r");
        retu
    }        Type: char[12]
             Size: 12 bytes
    printf("_fileno:%d\n", fp->_fileno);
    fclose(fp);
    return 0;
}

2.关闭文件

2.1 fclose函数原型

2.1.1 fclose函数

#include <stdio.h>

int fclose(FILE *stream);

函数简介:fclose 函数是 C 语言标准库中的一个函数,用于关闭文件指针所关联的文件。

函数参数:

stream:要关闭的文件指针。

函数返回值:

成功:返回0。

失败:返回EOF(-1)。

fclose 函数会执行以下操作:

  • 将缓冲区的内容刷新到磁盘中。
  • 关闭文件描述符。
  • 释放与文件相关的资源。

注意事项:

  • 在使用完文件指针后,应该及时使用 fclose 函数关闭文件,以避免资源泄漏。
  • 在关闭文件前,应确保文件指针有效,即不为 NULL。
  • 关闭文件后,不要再使用已关闭的文件指针进行文件操作,否则会导致未定义的行为。

3.stdin,stdout,stderr介绍

 图 3-1 stdin,stdout,stderr原理

Linux 系统使用三个标准流来处理数据:stdin(标准输入)、stdout(标准输出)和stderr(标准错误)。

Linux系统默认会打开stdin,stdout,stderr FILE文件指针,不需要用户程序主动打开。

stdin,stdout,stderr和普通的FILE没有什么区别,主要区别在于内核空间struct inode对应的文件类型不一样。

  • 标准输入(stdin)

标准输入通常表示为文件描述符 0。 它用于接收输入数据。 在命令行环境下,默认情况下与键盘绑定,用于从键盘读取用户输入。 在程序中,可以使用 stdin 来读取用户输入的数据。

  • 标准输出(stdout)

标准输出通常表示为文件描述符 1。 它用于输出程序的结果或信息。 在命令行环境下,默认情况下与终端绑定,将结果或信息显示在屏幕上。 在程序中,可以使用 stdout 来输出结果或信息。

  • 标准错误(stderr)

标准错误通常表示为文件描述符 2。 它用于输出程序的错误信息、警告或调试信息。 与标准输出不同,标准错误专门用于输出与程序执行相关的错误信息。 在命令行环境下,默认情况下也与终端绑定,将错误信息显示在屏幕上。 在程序中,可以使用 stderr 来输出错误信息。 

猜你喜欢

转载自blog.csdn.net/weixin_28673511/article/details/131921073
今日推荐