读取并删除txt文件中的第一行(或最后一行),而不复制
我想读取并删除txt文件中的第一行(不复制,它是一个很大的文件)。
我看过网络,但每个人都只是把想要的内容复制到一个新文件中。我不能那样做。
以下是第一次尝试。此代码将被隐藏在循环中,因为没有删除任何行。如果代码将在每次打开时删除文件的第一行,则代码将到达末尾。
#include <iostream>
#include <string>
#include <fstream>
#include <boost/interprocess/sync/file_lock.hpp>
int main() {
std::string line;
std::fstream file;
boost::interprocess::file_lock lock("test.lock");
while (true) {
std::cout << "locking
";
lock.lock();
file.open("test.txt", std::fstream::in|std::fstream::out);
if (!file.is_open()) {
std::cout << "can't open file
";
file.close();
lock.unlock();
break;
}
else if (!std::getline(file,line)) {
std::cout << "empty file
"; //
file.close(); // never
lock.unlock(); // reached
break; //
}
else {
// remove first line
file.close();
lock.unlock();
// do something with line
}
}
}
解决方案
您想做什么确实不容易。
如果您不小心打开同一个文件进行读写,您最终将读取您刚刚写入的内容,结果将不会是您想要的结果。
就地修改文件是可行的:只需打开它,在其中查找,修改并关闭。但是,您希望复制文件的所有内容,文件开头的K
字节除外。这意味着您必须以N
字节为单位反复读写整个文件。
现在,一旦完成,K
字节将保留在需要删除的末尾。我不认为有办法用溪流做到这一点。您可以使用unistd.h
中的ftruncate
或truncate
函数,也可以使用Boost.Interprocesstruncate
。
这里有一个例子(没有任何错误检查,我允许您添加它):
#include <iostream>
#include <fstream>
#include <unistd.h>
int main()
{
std::fstream file;
file.open("test.txt", std::fstream::in | std::fstream::out);
// First retrieve size of the file
file.seekg(0, file.end);
std::streampos endPos = file.tellg();
file.seekg(0, file.beg);
// Then retrieve size of the first line (a.k.a bufferSize)
std::string firstLine;
std::getline(file, firstLine);
// We need two streampos: the read one and the write one
std::streampos readPos = firstLine.size() + 1;
std::streampos writePos = 0;
// Read the whole file starting at readPos by chunks of size bufferSize
std::size_t bufferSize = 256;
char buffer[bufferSize];
bool finished = false;
while(!finished)
{
file.seekg(readPos);
if(readPos + static_cast<std::streampos>(bufferSize) >= endPos)
{
bufferSize = endPos - readPos;
finished = true;
}
file.read(buffer, bufferSize);
file.seekg(writePos);
file.write(buffer, bufferSize);
readPos += bufferSize;
writePos += bufferSize;
}
file.close();
// No clean way to truncate streams, use function from unistd.h
truncate("test.txt", writePos);
return 0;
}
我真的希望能够为就地修改文件提供更干净的解决方案,但我不确定是否有这样的解决方案。
相关文章