【问题标题】:How to truncate a file while it is open with fstream如何在使用 fstream 打开文件时截断文件
【发布时间】:2013-12-27 23:13:45
【问题描述】:

我知道可以用

截断文件
std::fstream fs(mypath, std::fstream::out | std::fstream::trunc);

但我需要读取文件,截断它,然后使用相同的文件句柄写入新内容(因此整个操作是原子的)。有人吗?

【问题讨论】:

  • 文件流不允许此功能 AFAIK。您必须使用trunc 关闭并重新打开文件流才能执行此操作。

标签: c++ std fstream


【解决方案1】:

我认为您不能获得“原子”操作,但使用现在已被接受为 Standard Library (C++17) 一部分的 Filesystem Technical Specification 您可以像这样调整文件的大小:

#include <fstream>
#include <sstream>
#include <iostream>
#include <experimental/filesystem> // compilers that support the TS
// #include <filesystem> // C++17 compilers

// for readability
namespace fs = std::experimental::filesystem;

int main(int, char*[])
{
    fs::path filename = "test.txt";

    std::fstream file(filename);

    if(!file)
    {
        std::cerr << "Error opening file: " << filename << '\n';
        return EXIT_FAILURE;
    }

    // display current contents
    std::stringstream ss;
    ss << file.rdbuf();
    std::cout << ss.str() << '\n';

    // truncate file
    fs::resize_file(filename, 0);
    file.seekp(0);

    // write new stuff
    file << "new data";
}

【讨论】:

    【解决方案2】:

    文件流不支持截断,除非打开文件。此外,这些操作无论如何都不会是“原子的”:至少,在 POSIX 系统上,您可以愉快地读取和写入已被另一个进程打开的文件。

    【讨论】:

      【解决方案3】:

      C++ 11 支持在 ofstream 上交换。我能想象的最好的做法是打开一个空文件并调用 swap。这不会是原子的,但尽可能接近。

      【讨论】:

        猜你喜欢
        • 2012-04-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-02
        • 1970-01-01
        • 1970-01-01
        • 2010-10-23
        相关资源
        最近更新 更多