【发布时间】:2013-12-27 23:13:45
【问题描述】:
我知道可以用
截断文件std::fstream fs(mypath, std::fstream::out | std::fstream::trunc);
但我需要读取文件,截断它,然后使用相同的文件句柄写入新内容(因此整个操作是原子的)。有人吗?
【问题讨论】:
-
文件流不允许此功能 AFAIK。您必须使用
trunc关闭并重新打开文件流才能执行此操作。
我知道可以用
截断文件std::fstream fs(mypath, std::fstream::out | std::fstream::trunc);
但我需要读取文件,截断它,然后使用相同的文件句柄写入新内容(因此整个操作是原子的)。有人吗?
【问题讨论】:
trunc 关闭并重新打开文件流才能执行此操作。
我认为您不能获得“原子”操作,但使用现在已被接受为 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";
}
【讨论】:
文件流不支持截断,除非打开文件。此外,这些操作无论如何都不会是“原子的”:至少,在 POSIX 系统上,您可以愉快地读取和写入已被另一个进程打开的文件。
【讨论】:
C++ 11 支持在 ofstream 上交换。我能想象的最好的做法是打开一个空文件并调用 swap。这不会是原子的,但尽可能接近。
【讨论】: