【发布时间】:2016-06-13 21:50:35
【问题描述】:
我想读取并删除 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\n";
lock.lock();
file.open("test.txt", std::fstream::in|std::fstream::out);
if (!file.is_open()) {
std::cout << "can't open file\n";
file.close();
lock.unlock();
break;
}
else if (!std::getline(file,line)) {
std::cout << "empty file\n"; //
file.close(); // never
lock.unlock(); // reached
break; //
}
else {
// remove first line
file.close();
lock.unlock();
// do something with line
}
}
}
【问题讨论】:
-
文件不能这样工作(类似于原始数组,如果不将所有剩余元素向上移动一个槽,则无法删除第一个元素)。
-
if语句的每个分支都有file.close(); lock.unlock();。std::file对象的析构函数将关闭文件,因此您无需显式关闭它(当file.is_open()返回 false 时,无需关闭它)。毫无疑问,Boost 中有一个 RAII 类型来管理该锁,并使用析构函数来解锁它。 -
我认为这个问题与截断前面的文件有关。一种选择是将第一行之后的数据移动到文件的开头。但是对于更大的文件,这将是昂贵的。另请检查:stackoverflow.com/questions/706167/truncate-file-at-front
-
@user1587451 - 文件有多大,目标操作系统是什么,是 windows 吗?立即想到的解决方案是对文件进行内存映射,然后简单地使用 memmove 或 memcpy 将字节移回第一行的长度。虽然这仍然是最严格意义上的复制,但您将利用操作系统来完成它,这将负责几乎所有繁重的工作。如果文件小于 4GB,则可以使用 C 和 WindowsAPI 轻松完成。
标签: c++ fstream getline stdstring boost-interprocess