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

news2024/12/24 8:25:01

目录

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函数原理

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 来输出错误信息。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/788140.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

电脑丢失msvcp140.dll的解决方法分享

如果你在使用电脑时遇到了“找不到msvcp140.dll”的错误提示&#xff0c;别着急&#xff01;这并不是什么严重的问题&#xff0c;电脑丢失msvcp140.dll的解决方法分享&#xff0c;只要你按照以下方法进行处理&#xff0c;很快就能够顺利地解决它。 一.什么是msvcp140.dll msvc…

Spring Boot与MyBatis结合 实现对mock平台改造

上一章&#xff1a; 测开工具&#xff1a;spring boot 实现mock平台_springboot搭建mock_做测试的喵酱的博客-CSDN博客 代码地址&#xff1a; GitHub - 18713341733/mock: Spring Boot与MyBatis结合 实现对mock平台改造 一、背景 读取数据改为从mysql数据库中读取。 Sp…

RDIFramework.NET CS敏捷开发框架 V6.0发布(支持.NET6+、Framework双引擎,全网唯一)

全新RDIFramework.NET V6.0 CS敏捷开发框架发布&#xff0c;全网唯一支持.NET6&#xff0c;Framework双引擎&#xff0c;降低开发成本&#xff0c;提高产品质量&#xff0c;提升用户体验与开发团队稳定性&#xff0c;做软件就选RDIFramework.NET开发框架。 1、RDIFramework.NET…

主从复制高级进阶

从主库入手&#xff1a; 关闭 主&#xff1a;修改配置文件 /etc/my.cnf 查看日志 查看 从&#xff1a; 修改重启 重启后报错&#xff0c;可能是uuid相同&#xff0c;要修改 查看状态 都是yes 从 从库入手 修改配置文件重启 从3&#xff1a; 从2&#xff1a; 先停止slave …

redis中使用bloomfilter的白名单功能解决缓存预热问题

一 缓存预热 1.1 缓存预热 将需要的数据提前缓存到缓存redis中&#xff0c;可以在服务启动时候&#xff0c;或者在使用前一天完成数据的同步等操作。保证后续能够正常使用。 1.2 解决办法PostConstruct注解初始化

微服务框架入门

微服务 微服务是一种经过良好架构设计的分布式架构方案&#xff0c;微服务架构特征&#xff1a; 单一职责&#xff1a;微服务拆分粒度小&#xff0c;每一个服务都对应唯一的业务能力&#xff0c;做到单一职责&#xff0c;避免重复业务开发面向服务&#xff1a;微服务对外暴露…

闲置旧手机搭建服务器?在安卓手机上使用Termux搭建web服务「公网远程访问」

文章目录 概述1.搭建apache2.安装cpolar内网穿透3.公网访问配置4.固定公网地址5.添加站点 概述 Termux是一个Android终端仿真应用程序&#xff0c;用于在 Android 手机上搭建一个完整的Linux 环境&#xff0c;能够实现Linux下的许多基本操作&#xff0c;不需要root权限Termux就…

MobileViG实战:使用MobileViG实现图像分类任务(一)

文章目录 摘要安装包安装timm安装 grad-cam 数据增强Cutout和MixupEMA项目结构计算mean和std生成数据集 摘要 论文翻译&#xff1a;https://blog.csdn.net/m0_47867638/article/details/131860981?spm1001.2014.3001.5502 官方源码&#xff1a;https://github.com/SLDGroup/M…

Qt Core学习日记——第四天QMetaEnum(下)

类定义&#xff1a; 成员变量就只有QMetaObject *mobj和uint handle&#xff0c;handle同样用于计算在qt_meta_stringdata_XTest的位置 成员函数&#xff1a; 接下以test类进行函数讲解 test.h #pragma once #include <qobject.h> #include <QFlags> class X…

源码跟踪,案例详解Spark的分区规则

水善利万物而不争&#xff0c;处众人之所恶&#xff0c;故几于道&#x1f4a6; 目录 一、默认分区规则 1. 从集合中创建RDD - makeRDD   2. 读取外部存储系统创建RDD - textFile 二、指定分区规则 1. 从集合中创建RDD指定分区 - makeRDD   2. 读取外部存储系统创建RDD指定分…

基于Java+SpringBoot+vue前后端分离甘肃非物质文化网站设计实现

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

TCP/UDP的首部

TCP/UDP首部信息 TCP首部第一个4字节第二个4字节与第三个4字节第四个4字节第五个4字节选项最大报文段长度&#xff08;MSS&#xff09;选项窗口扩大选项时间戳选项 什么时候发送RST包UDP首部 TCP首部 TCP 首部长度为20字节&#xff0c;加上选项部分最大可达60字节。 第一个4…

移动端商品详情页设计

效果图 代码如下 页面设计 <div class"container"><!--商品详情 start--><van-image class"goods-item-image" :src"goods.goodsHeadImg"></van-image><div class"goods-price">&#xffe5;<span&…

MySQL函数讲解(谓词、CASE)

目录 MySQL常见函数 字符串函数 进行字符串操作的函数 算术函数 进行数值计算的函数 日期函数 进行日期操作的函数 转换函数 进行数据类型和值转换的函数 流程函数 进行条件删选 聚合函数 进行数据聚合的函数 谓词 一般用于条件判断 什么是函数 函数指一段可以直接被…

web前端tips:js继承——原型链继承

原型链继承 原型链继承是 JavaScript 中实现继承的一种方式&#xff0c;它通过使用原型来实现对象之间的继承关系。 在 JavaScript 中&#xff0c;每个对象都有一个原型&#xff08;prototype&#xff09;&#xff0c;它是一个指向另一个对象的引用。当我们访问一个对象的属性…

Quartz线程调度源码分析

Quartz作为任务调度的组件&#xff0c;其中涉及到多种线程&#xff0c;主要分为主线程、调度线程和工作线程。 主线程&#xff1a;创建Quartz的调度工厂(SchedulerFactory)、调度器(Scheduler)、触发器(Trigger)、任务&#xff08;Job&#xff09;并启动调度器的线程。这里的主…

Pytest结合数据驱动-yaml

Pytest 结合数据驱动 YAML 数据驱动 什么是数据驱动&#xff1f; 数据驱动就是数据的改变从而驱动自动化测试的执行&#xff0c;最终引起测试结果的改变。简单来说&#xff0c;就是参数化的应用。数据量小的测试用例可以使用代码的参数化来实现数据驱动&#xff0c;数据量大的…

Ceph社区上游正式合入openEuler原生支持,并通过CI持续验证

作为覆盖全场景应用、支持多样性算力的面向数字基础设施的开源操作系统&#xff0c;openEuler始终遵循“上游优先”的策略&#xff0c;帮助上游开源软件原生支持openEuler&#xff0c;让openEuler系操作系统的用户可以在开发、集成、使用这些开源软件或基于这些开源软件的产品和…

比较版本号(力扣)思维 JAVA

给你两个版本号 version1 和 version2 &#xff0c;请你比较它们。 版本号由一个或多个修订号组成&#xff0c;各修订号由一个 ‘.’ 连接。每个修订号由 多位数字 组成&#xff0c;可能包含 前导零。每个版本号至少包含一个字符。修订号从左到右编号&#xff0c;下标从 0 开始…

vue3+ts+elementui-plus二次封装树形表格

复制粘贴即可&#xff1a; 一、定义table组件 <template><div classmain><div><el-table ref"multipleTableRef" :height"height" :default-expand-all"isExpend" :data"treeTableData"style"width: 100%…