【问题标题】:Should I use string or ostringstream or stringstream for fileIO in C++我应该在 C++ 中对 fileIO 使用 string 或 ostringstream 还是 stringstream
【发布时间】:2021-11-29 01:51:09
【问题描述】:

我想使用 C++ 使用 fstreams 写入大文件的开头。
我想出的方法是将整个数据写入一个临时文件,然后写入原始文件,然后将数据从tmp文件复制到原始文件中。

我想创建一个缓冲区,它将数据从原始文件传输到 tmp 文件,反之亦然。
该过程适用于所有人stringostringstreamstringstream。我希望数据的复制速度快,而且内存消耗最少。

示例string

void write(std::string& data)
{
    std::ifstream fileIN("smth.txt");
    std::ofstream fileTMP("smth.txt.tmp");
    std::string line = "";

    while(getline(fileIN, line))
        fileTMP << line << std::endl;

    fileIN.close();
    fileTMP.close();

    std::ifstream file_t_in("smth.txt.tmp"); // file tmp in
    std::ofstream fileOUT("smth.txt");
    fileOUT << data;

    while(getline(file_t_in, line)
        fileOUT << line << std::endl;

    fileOUT.close();
    file_t_in.close();

    std::filesystem::remove("smth.txt.tmp");
}

我应该使用 string 还是 ostringstreamstringstream

使用一个比另一个有什么优势?

【问题讨论】:

标签: c++ string stringstream ostringstream


【解决方案1】:

假设至少有一些操作并且您没有复制两次相同的数据以以未更改的文件结尾,那么可能的改进(恕我直言)是:

  • 不要在循环中使用std::endl,而只能使用'\n'"\n"std::endl 确实写了一个行尾,但也会在底层流上强制刷新,这在循环内是无用且昂贵的。
  • 您的代码将数据复制了两次。如果可能的话,通过复制(就像您的代码当前所做的那样)构建临时文件,然后删除旧文件并用原始名称重命名临时文件,效率会更高。这样一来,您只需复制一次数据,因为重命名文件是一种成本低廉的操作。

【讨论】:

    【解决方案2】:

    不用手动复制,有std::filesystem::copy

    如果您真的想使用文件流进行复制,可以使用单行:output_stream &lt;&lt; input_stream.rdbuf();

    如果你真的想用循环手动复制,它不必是基于行的。使用固定大小的缓冲区。

    【讨论】:

    • 请注意,如果目标文件已经存在,std::filesystem::copy(_file)() 将失败,除非指定了 overwrite_existing 选项标志。还有std::filesystem::rename(),所以你可以删除目标文件,然后将新文件重命名为旧名称而不执行复制。
    猜你喜欢
    • 2010-11-30
    • 2011-03-20
    • 1970-01-01
    • 2011-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多