如何覆盖当前文件

How can the current file be overwritten?

本文关键字:文件 覆盖 何覆盖      更新时间:2023-10-16

对于以下代码:

fstream file("file.txt", ios::in):
//some code
//"file" changes here
file.close();
file.clear();
file.open("file.txt", ios::out | ios::trunc);

如何更改最后三行,使当前文件不是关闭的,而是"重新打开"所有内容?

如果我正确理解这个问题,您希望在不关闭文件的情况下清除文件的所有内容(即通过设置EOF位置将文件大小设置为0)。据我所知,你提出的解决方案是最吸引人的。

您的另一个选择是使用特定于操作系统的函数来设置文件的末尾,例如,在Windows上的SetEndOfFile()或在POSIX上的truncate()。

如果你只想从文件的开头开始写作,Simon的解决方案是可行的。在不设置文件结尾的情况下使用它可能会使您处于这样一种情况,即您的垃圾数据超过了您编写的最后一个位置。

您可以倒带文件:将放置指针放回文件的开头,这样下次您写东西时,它将覆盖文件的内容。为此,您可以像这样使用seekp

fstream file("file.txt", ios::in | ios::out); // Note that you now need
                                              // to open the file for writing
//some code
//"something" changes here
file.seekp(0); // file is now rewinded

请注意,它不会擦除任何内容。只有当您覆盖它时,请小心。

我猜您正试图避免传递"file.txt"参数,并试图实现类似的东西

void rewrite( std::ofstream & f )
{
   f.close();
   f.clear();
   f.open(...); // Reopen the file, but we dont know its filename!
}

然而,ofstream没有提供底层流的文件名,也没有提供清除现有数据的方法,所以你有点运气不好。(它确实提供了seekp,它可以让您将写光标放回文件的开头,但不会截断现有内容…)

我要么只将文件名传递给需要它的函数

void rewrite( std::ostream & f, const std::string & filename )
{
   f.close();
   f.clear();
   f.open( filename.c_str(), ios::out );
}

或者将文件流和文件名打包到一个类中。

class ReopenableStream
{
   public:
     std::string filename;
     std::ofstream f;
     void reopen()
     {
       f.close();
       f.clear();
       f.open( filename.c_str(), ios::out );
     }
     ...
};

如果你觉得过于热情,你可以让ReopenableStream实际上表现得像一个流,这样你就可以写reopenable_stream<<foo;而不是reopenable_stream.f<<foo,但IMO似乎有些过头了。