我目前正在使用以下代码删除.txt文件的最后一行。它有效,但速度很慢。我该怎么做才能优化这段代码?
string line;
vector<string> lines;
std::ifstream inputStream("example.txt");
while (getline(inputStream,line)) {
lines.push_back(line);
}
inputStream.close();
std::fstream outputStream("example.txt", ios::out | ios::trunc);
if (outputStream.is_open())
{
for (int i=0; i < lines.size()-2; i++)
{
outputStream << lines[i] << "\n";
}
outputStream.close();
}
答案 0 :(得分:2)
有一些与操作系统相关的功能可以改变文件的大小。
在Unix世界中,使用truncate():http://linux.die.net/man/2/truncate
在Windows世界中,使用SetEndOfFile():http://www.google.com/search?btnI=1&q=msdn+SetEndOfFile
这两种技术都需要获取OS文件句柄并以这种方式使用文件进行dinking。如果你想这样做,我会编写一个带有文件名和新大小的函数。
这就留下了寻找新尺寸的问题。我认为从后面扫描有可能比从前面扫描更有效,但这对读者来说无论如何都是一种练习。
答案 1 :(得分:2)
无需在内存中缓冲整个文件。相反,您可以在阅读原始文件时写入第二个临时文件。写入第二个文件并关闭第一个文件后,可以将临时文件重命名为主文件(在UNIX上,一旦打开主文件,您也可以remove()
并直接写入文件,打开它在remove()
d)之后输入:
{
std::ifstream in("example.txt");
std::ofstream out("example.tmp");
// some error checking...
std::string line;
std::getline(line);
for (std::string tmp; std::getline(tmp); line.swap(tmp)) {
out << line << '\n';
}
if (!out.close()) {
// seems the output couldn't be written: deal with it somehow
}
}
std::rename("example.tmp", "example.txt");
答案 2 :(得分:1)
根据文件的大小,您可能会发现从末尾(以块为单位)实际读取文件的速度更快,并保存最后一行的位置。然后,您可以将文件的一部分从头开始复制到所需的位置。这样,您就不必进行如此多的IO操作。
所以实际算法会是这样的: