Yip*_*Yay 21 c# c++ io performance file
可能重复:
删除C#中文本文件的第一行
从巨大的(想想2-3 GB)文件中删除第一行的最快最聪明的方法是什么?
我认为,你可能无法避免重写整个文件,但我可能错了.
可以使用内存映射文件以某种方式帮助解决这个问题?
是否可以通过直接在文件系统上运行来实现此行为(例如,NTFS) - 例如,更新相应的inode
数据并更改文件的起始扇区,以便忽略第一行?如果是的话,这种方法是否真的很脆弱,或者还有许多其他应用程序,除了OS
本身做类似的东西?
Omn*_*ity 13
NTFS
默认情况下,在大多数卷上(但重要的是不是全部!)以4096
字节块的形式存储数据.这些由$MFT
记录引用,您无法直接编辑,因为操作系统不允许这样做(出于理智的原因).因此,没有任何技巧可用于操作文件系统以执行接近您想要的操作(换句话说,您无法直接反向截断NTFS上的文件,即使在文件系统块大小的数量中也是如此.)
由于文件存储在文件系统中的方式,唯一的答案是您必须直接重写整个文件.或者找出一种不同的方式来存储您的数据.一个2-3GB的文件是庞大而疯狂的,特别是考虑到你提到的行意味着这些数据至少部分是文本信息.
您应该考虑将这些数据放入数据库中吗?或者至少更有效地组织它.
您可以覆盖要删除的每个字符'\x7f'
.然后,当读入文件时,您的读者会忽略该字符.当然,这假设您有一个永远不会使用该DEL
字符的文本文件.
std::istream &
my_getline (std::istream &in, std::string &s,
char del = '\x7f', char delim = '\n') {
std::getline(in, s, delim);
std::size_t beg = s.find(del);
while (beg != s.npos) {
std::size_t end = s.find_first_not_of(del, beg+1);
s.erase(beg, end-beg);
beg = s.find(del, beg+1);
}
return in;
}
Run Code Online (Sandbox Code Playgroud)
正如亨克指出的那样,你可以选择一个不同的角色来扮演你的角色DELETE
.但是,优点是无论您要删除哪一行(不仅限于第一行),该技术都可以工作,并且不需要使用文件系统.
使用修改过的阅读器,您可以定期对文件进行"碎片整理".或者,碎片整理可以自然地发生,因为内容被流式传输/合并到不同的文件中或存档到不同的机器.
编辑:您没有明确说出来,但我猜这是针对某种日志记录应用程序,其目标是在日志文件的大小上设置上限.但是,如果这是目标,则使用较小的日志文件集合要容易得多.假设您保留了大约10MB的日志文件,总日志限制为4GB.那将是大约400个文件.如果启动了第401个文件,则对于每个写入的行,您可以DELETE
在第一个文件中的连续行上使用该标记.当所有行都被标记为删除时,可以删除文件本身,再次为您留下大约400个文件.只要在删除行时第一个文件没有关闭,就没有隐藏的O(n 2)行为.
但更简单的是允许您的日志记录系统按原样保留1st和401st文件,并在移动到402nd文件时删除第一个文件.