[现代C++]读写文件

2024-07-18 13:34:03 浏览数 (2)

昨天的文章中叙述了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 filen";
    }
    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 filen";
    }


    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的方法,提高读写文件的健壮性。

0 人点赞