C/C++之fopen

news/2024/7/7 18:38:55

前言

在我们需求开发中,经常需要读取文件的内容,在C++中,通常使用open/close或者fopen/fclose来完成这个功能,那么open与fopen有什么异同呢,在开发中我们应当如何选择这两个函数呢,我们一起来看一下。

1.fopen和open的区别

  1. 来源不同
  • open是unix系统调用函数,其返回值是文件描述符,是文件描述符表里的索引值。
  • fopen是ANSIC标准中的C语言库函数,在不同的系统中应该调用不同的内核API,返回的是一个指向文件结构的指针。
  1. 可移植性
  • fopen是C标准函数,具有良好的可移植性。
  • open是unix系统调用,可移植性有限。
  1. 使用范围

    open返回文件描述符,文件描述符是unix下同下的重要概念,在unix系统下,对一切设备都是以文件的形式进行操作,除了Regular文件之外,其他比如网络套接字,硬件设备等都是以文件的形式操作。

  2. 文件IO层次

    从文件IO的角度来看,open属于低级IO函数,fopen属于高级IO函数,低级和高级的简单区分标准是与系统内核的距离,即open距离系统内核较近,运行在内核态,fopen距离系统内核较远,运行在用户态。

  3. 是否有缓冲区

    open没有缓冲区,fopen有缓冲区

  • 缓冲文件系统

    在内存开辟一个"缓冲区",为程序中的每一个文件使用,当执行文件读操作时,将磁盘上的文件数据先读入内存"缓冲区",当缓冲区被装满后再从缓冲区依次读入接收的变量。执行写文件的操作时,先将数据写入内存"缓冲区",待内存缓冲区装满后再写入文件。所以,内存缓冲区的大小影响着实际操作外存的次数,内存缓冲区越大,则操作外存的次数就越少,用户态与内核态的切换越少,执行速度就越快,效率高,文件缓冲区的大小随机器而定。fopen具有缓冲区。

  • 非缓冲文件系统

    缓冲文件系统借助文件结构体指针来对文件进行管理,通过文件指针来对文件进行访问,即可以读写字符、字符串、格式化数据,也可以读写二进制数据。非缓冲文件系统依赖于操作系统,通过操作系统的功能对文件进行读写,是系统级别的输入输出,每次调用都需要进行用户态与内核态的切换,它不设文件结构体指针,只能读写二进制文件,但效率高,速度快,但是由于ANSIC标准不再包括非缓冲文件系统,因此不建议使用没有缓冲区的函数。open没有缓冲区。

2.常用缓冲区函数

fopen/fclose

/*
*path 文件,
FILE *fp 返回值
*mode 模式
       "r"           打开文字文件只读
       "w"           创建文字文件只写
       "a"           增补, 如果文件不存在则创建一个
       "r+"          打开一个文字文件读/写
       "w+"          创建一个文字文件读/写
       "a+"          打开或创建一个文件增补
       "b"           二进制文件(可以和上面每一项合用)
       "t"           文这文件(默认项)
————————————————
*/

 #include <stdio.h>
 FILE *fopen(const char *path, const char *mode);
 int fclose(FILE *fp);

fread/fwrite

#include <stdio.h>

/*
从stream所指向的文件中读取数据块,读取的字节数为size*nmemb,读取来的数据存放在buffer为起始地址的内存中。若fread函数的返回值等于nmemb,则执行本函数读取数据成功;若文件结束或发生错误,返回值等于0。
ptr:存放数据的内存起始地址
size:数据块的大小
nmemb:读取数据块的数量
fp:文件结构体指针
*/

 size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
  
  /*
  fwrite:将内存中从ptr地址开始的数据往stream所指向的文件里写,写入到文件里的字节数为size*nmemb。返回值同上。
  */

 size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);

/*
fseek用于重定位流(数据流/文件)上的文件内部位置指针的位置。
stream :文件FILE
offset :偏移量
whence  : 1、SEEK_SET  光标移至头
          2、SEEK_END  光标移至尾巴
          3、SEEK_CUR  光标当前位置
*/

int fseek(FILE *stream, long offset, int whence);

/*
ftell 用于得到文件位置指针当前位置相对于文件首的偏移字节数

stream:指向 FILE 对象的指针,该 FILE 对象标识了流.
*/

long ftell(FILE *stream);

/*
rewind 将文件内部的位置指针重新指向一个流(数据流/文件)的开头。
stream:指向 FILE 对象的指针,该 FILE 对象标识了流.
*/

void rewind(FILE *stream);

3.IO函数示例

读取文件内容到字符串

    FILE* ini = fopen(AuBackUpIni, "r");
    if(!ini) {
        printf("open %s failed\n", AuBackUpIni);
        return false;
    }
    fseek(ini, 0, SEEK_END);
    size_t size = ftell(ini);
    char* where = new char[size];
    rewind(ini);
    fread(where, sizeof(char), size, ini);
    printf("where=%s\n", where);
   fclose(ini);

写字符串到文件

FILE* fp = fopen(versionFilePath, "w");
    if(!fp) {
        printf("open %s file failed\n", versionFilePath);
        return false;
    }
    fprintf(fp, "%s", versionInfo);
    fclose(fp);

这就是本篇文章要跟大家分享的内容,希望大家每天坚持进步~

给个赞支持一下,谢谢啦~

本文由 mdnice 多平台发布


http://lihuaxi.xjx100.cn/news/804000.html

相关文章

图解LeetCode——1145. 二叉树着色游戏(难道:中等)

一、题目 有两位极客玩家参与了一场「二叉树着色」的游戏。游戏中&#xff0c;给出二叉树的根节点 root&#xff0c;树上总共有 n 个节点&#xff0c;且 n 为奇数&#xff0c;其中每个节点上的值从 1 到 n 各不相同。 最开始时&#xff1a; 「一号」玩家从 [1, n] 中取一个值…

软件测试基础(五) 之 了解测试团队的组织架构

今天来了解一下软件测试团队的组织架构模式到底是什么样子。测试团队的组织架构模式的分类一个公司软件测试的组织架构&#xff0c;可能会决定你未来的成长空间&#xff0c;同时也决定了我们的工作模式到底是什么样子。现在测试行业内通常测试团队的组织架构主要分成两种&#…

Exynos 4412 看门狗定时器中断

如果想弄懂看门狗定时器中断&#xff0c;要掌握下面两个知识点&#xff1a; 1 懂寄存器 Cortex A9采用的是ARM官方规定的中断处理机制 有两大类寄存器决定了中断工作状态 1) exynos 4412 特有的寄存器(在第26章) 2) Cortex A9 规定的工作寄存器(在第9章和第10章) 2 懂中断处理过…

前端面试套题系列(第二篇)

1、HTML 语义化标签 语义化标签,旨在让标签有自己的含义,优势是: (1) 使得在没有 CSS 的情况下,页面也能呈现出很好的内容结构、代码结构 (2) 有利于 SEO:和搜索引擎建立良好沟通,有助于爬虫抓取更多的有效信息 (3) 方便其他设备(比如盲人阅读器来解析)来解析 HT…

【信管11.1】项目采购相关知识及过程

项目采购相关知识及过程项目采购管理过程做为十大知识领域的最后一部分内容&#xff0c;含金量也是不容忽视的。在这一大章节中&#xff0c;除了普通的采购管理过程之外&#xff0c;我们还要学习采购相关的一些法规知识、合同相关知识等。总之&#xff0c;内容不少&#xff0c;…

【Python学习笔记】12. 字符串

前言 字符串是 Python 中最常用的数据类型。我们可以使用引号( ’ 或 " )来创建字符串。 Python3 字符串 字符串是 Python 中最常用的数据类型。我们可以使用引号( ’ 或 " )来创建字符串。 创建字符串很简单&#xff0c;只要为变量分配一个值即可。例如&#xf…

python爬虫正则表达式

博主简介&#xff1a;博主是一个大二学生&#xff0c;主攻人工智能领域研究。感谢缘分让我们在CSDN相遇&#xff0c;博主致力于在这里分享关于人工智能&#xff0c;C&#xff0c;python&#xff0c;爬虫等方面的知识分享。如果有需要的小伙伴&#xff0c;可以关注博主&#xff…

c++11 标准模板(STL)(std::multiset)(六)

定义于头文件 <set> template< class Key, class Compare std::less<Key>, class Allocator std::allocator<Key> > class multiset;(1)namespace pmr { template <class Key, class Compare std::less<Key>> usi…