可能是重复问题:
在C#中删除文本文件的第一行
从一个巨大的文件(想象一下2-3GB)中删除第一行,最快最聪明的方法是什么?
我认为,你可能无法避免逐块重写整个文件,但我可能错了。
使用内存映射文件是否有助于解决此问题?
是否可以通过直接操作文件系统(例如NTFS)来实现此行为 - 比如更新相应的
inode
数据并更改文件起始扇区,以忽略第一行?如果是,则这种方法是否真的很脆弱,或者除了OS
本身之外还有许多其他应用程序执行类似的操作?
可能是重复问题:
在C#中删除文本文件的第一行
从一个巨大的文件(想象一下2-3GB)中删除第一行,最快最聪明的方法是什么?
我认为,你可能无法避免逐块重写整个文件,但我可能错了。
使用内存映射文件是否有助于解决此问题?
是否可以通过直接操作文件系统(例如NTFS)来实现此行为 - 比如更新相应的inode
数据并更改文件起始扇区,以忽略第一行?如果是,则这种方法是否真的很脆弱,或者除了OS
本身之外还有许多其他应用程序执行类似的操作?
NTFS
卷将数据存储在 4096
字节的块中。这些由 $ MFT
记录引用,您无法直接编辑该记录,因为操作系统禁止这样做(出于理智的原因)。因此,在文件系统上操作以实现所需效果的方法并不存在(换句话说,在 NTFS 上不能直接按文件系统块大小逆向截断文件)。'\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;
}
DELETE
。但是,这种技术的优点在于,它无论要删除哪一行(不限于第一行),都能起作用,并且不需要对文件系统进行任何调整。DELETE
标记来删除连续的行。当所有行都被标记为删除时,文件本身可以被删除,使您再次拥有大约400个文件。只要第一个文件在删除行时没有关闭,就没有隐藏的O(n²)行为。\0
覆盖。不过这完全取决于读者以及它能够被适应到多大程度。 - H HIdea(没有魔法,只有下面的辛勤工作):
使用用户模式文件系统,如http://www.eldos.com/cbfs/或http://dokan-dev.net/en/,将其包装在真实文件系统周围,并创建一个小型簿记系统以跟踪前面“吃掉”的文件数量。在某些时候,当文件变得太大时,将文件重写到另一个文件中并重新开始。
这个想法怎么样?
编辑:
如果你选择虚拟文件系统,那么你可以使用更小的(256mb)文件片段,然后将它们粘合成一个带有所需偏移量的“虚拟”文件。这样,你就永远不需要重新编写文件。
更多:
关于“覆盖”前几行的想法的反思 - 不要那样做,相反,在文件的前面添加一个64位整数,并使用任何你喜欢的方法跳过那么多字节,例如Stream
派生,它将包装原始流并在其中进行偏移读取。
如果你选择在“客户端”侧使用包装器,我想这可能更好。
将文件分成两部分,第一部分是较小的块。 删除第一行,然后与另一部分连接。