前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[现代C++]读写文件

[现代C++]读写文件

作者头像
程序员的园
发布2024-07-18 13:34:03
120
发布2024-07-18 13:34:03
举报
文章被收录于专栏:程序员的园——原创文章

昨天的文章中叙述了C++17的文件系统操作,极大的方便了对于文件夹的操作,见链接[现代C++]文件系统操作。今天将更深一步的讲解文件的读写。

C方法读写文件

C++沿袭了C的读写文件的方法,示例代码如下,(此方法可以忽略,直接读下一节)

代码语言:javascript
复制
constexpr int buffer_length = 12;
void test_fwrite(){
    //"wb"表征以二进制写的形式打开文件,
    //不同的模式对应不同的类型
    auto file = fopen("d://1.txt","wb");
    if (!file){
        std::cout<<"failed to open file\n";
    }
    char* buffer = (char*)malloc(buffer_length);
    std::memset(buffer,0,buffer_length);
    for (size_t i = 0; i < buffer_length; i++){
        char c = 65+i;
        std::memcpy(buffer+i,&c,1);
    }
    fwrite(buffer,1,buffer_length,file);
    free(buffer);
    fclose(file);
}



void test_fread(){
    //"rb"表征以二进制读的形式打开文件
    //不同的模式对应不同的类型
    auto file = fopen("d://1.txt", "rb");
    if (!file){
        std::cout << "failed to open file\n";
    }


    fseek(file, 0, SEEK_END);
    size_t fileSize = ftell(file);
    fseek(file, 0, SEEK_SET);



    char* buffer = (char*)malloc(fileSize);
    std::memset(buffer, 0, fileSize);
    auto read_size = fread(buffer, 1, buffer_length, file);


    for (size_t i = 0; i < read_size; i++){
        std::cout<<*((char*)buffer+i)<<"\t";
    }
    std::cout<<"\n";
    free(buffer);
    fclose(file);
}

由以上的示例代码可知,打开的文件必须在使用完后调用fclose关闭。一旦忘记关闭打开的文件便会出现资源泄露。

fstream读写文件

fstream可以用来读写文件,其实自C++98以来fstream已在标准库中,只是C++11及以后扩展了其功能,改善了文件处理方式。<fstream>C++的标准库<fstream>提供了std::ifstream(输入流)、std::ofstream(输出流)和std::fstream(输入输出流)三个类,分别用于文件的读取、写入和读写操作。

示例代码如下:

代码语言:javascript
复制
#include<fstream>
#include<string>


void writeFile(conststd::string&filename) {
    //std::ios_base::out表征输出模式


    //std::ofstream outFile;
    //outFile.open(filename,std::ios_base::out);


    std::ofstream outFile(filename,std::ios_base::out);
    if (!outFile) {
        std::cerr << "Failed to open the file for writing." << std::endl;
        return;
    }


    outFile << "Hello, Modern C++ File Writing!" << std::endl;
    // 自动关闭文件,也可以显式调用outFile.close();
}


void readFile(conststd::string&filename) {
    //std::ios_base::in表征输入模式
    //std::ios_base::binary表征二进制模式
    std::ifstream inFile(filename, std::ios_base::in|std::ios_base::binary);
    if (!inFile) {
        std::cerr << "Failed to open the file for reading." << std::endl;
        return;
    }


    std::string line;
    while (std::getline(inFile, line)) {
        std::cout << line << std::endl;
    }
    // 文件自动关闭
}

由如上代码可知:

  • 打开文件的模式以枚举的形式呈现,不再是字符串的形式出现,易读性和使用便利性更方便。
  • 打开的文件不再需要手动关闭。fstream利用RAII的思想管理其打开的资源。

结合文件系统的文件读写

在文件读写之前对于路径有效性进行判断是非常有必要的,详细的路径检查见链接[现代C++]文件系统操作。简单的示例代码如下:

代码语言:javascript
复制
#include<fstream>
#include<filesystem>


void writeToFileUsingFS(conststd::filesystem::path&filePath) {
    std::ofstream outFile(filePath);
    if (!outFile) {
        std::cerr << "Failed to open " << filePath << " for writing." << std::endl;
        return;
    }
    outFile << "File operation with std::filesystem." << std::endl;
}


void readFromFileUsingFS(conststd::filesystem::path&filePath) {
    if (!std::filesystem::exists(filePath)) {
        std::cerr << filePath << " does not exist." << std::endl;
        return;
    }
    
    std::ifstream inFile(filePath);
    if (!inFile) {
        std::cerr << "Failed to open " << filePath << " for reading." << std::endl;
        return;
    }
    
    std::string content((std::istreambuf_iterator<char>(inFile)),std::istreambuf_iterator<char>());
    std::cout << content << std::endl;
}

由以上代码可知,在读文件前对文件进行存在性检测,增加代码的健壮性。

结语

本文在指出C方法读写文件缺陷的基础上,引出了fstream提供的读写文件新方法。fstream在RAII思想加持下完成文件资源的自动回收。继而提出了结合std::filesystem和fstream的方法,提高读写文件的健壮性。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-05-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员的园 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档