将单个字符添加到多GB文件(在我的实际情况下是40GB文件)中,性能最佳的方法是什么。
执行此操作没有限制。这意味着它可以通过工具,shell脚本,任何编程语言的程序,......
答案 0 :(得分:8)
没有真正简单的解决方案。没有系统调用来预先添加数据,只是附加或重写。
但是根据你对文件的处理方式,你可能会侥幸逃脱。
如果按顺序使用文件,您可以创建named pipe并放置cat onecharfile.txt bigfile > namedpipe
,然后使用“namedpipe”作为文件。如果您的程序将stdin作为输入,则cat onecharfile.txt bigfile | program
可以实现相同的目的。
对于随机访问,可以完成FUSE文件系统,但可能对此过于复杂。
如果你想让自己的手真的很脏,请弄明白如何
这有可能严重破坏你的文件系统,所以不推荐;很有趣。
答案 1 :(得分:4)
让文件有一个初始的空字符块。在前置字符时,读取块,从右到左插入字符,然后写回块。当块已满时,然后执行更昂贵的完全重写以便预先添加另一个空块。这样,您可以减少必须进行完全重写的大部分因素。
补充:将文件保存在两个子文件中:A(短一个)和B(长一个)。以你喜欢的任何方式前置A.当A变得“足够大”时,将A添加到B(通过重写),然后清除A。
另一种方法:将文件保存为小文件目录...,A000003,A000002,A000001。
只是前置到编号最大的文件。当它足够大时,按顺序制作下一个文件
当您需要读取文件时,只需按降序读取它们。
答案 2 :(得分:2)
您可能可以根据您的问题反转您的实现:将单个字符附加到文件的末尾。到了读取文件的时候,请在 reverse 中读取它。
将此隐藏在足够的抽象层之后,它可能不会对您的代码如何物理存储字节产生影响。
答案 3 :(得分:1)
如果您使用linux,您可以尝试使用加载了LD_PRELOAD的自定义版本的READ(2),并在第一次读取时将其添加到数据之前。
请参阅https://zlibc.linux.lu/zlibc.html了解实施灵感。
答案 4 :(得分:0)
如果你的意思是将该字符预先添加到整个文件的开头,单向
$ echo "C" > tmp
$ cat my40gbfile >> tmp
$ mv tmp my40gbfile
或使用sed
$ sed -i '1i C' my40gbfile
如果你的意思是将字符前置到文件的每一行
$ awk '{print "C"$0}' my40gbfile > temp && mv temp my40gbfile
答案 5 :(得分:0)
据我所知,这是在文件系统级别处理的,这意味着如果您将数据添加到文件中,它会有效地重写文件。这与MP3文件中的ID3标签零填充的原因相同,因此未来的更新不会重写整个文件,只是更新那些保留的字节。
因此,无论您使用哪种方式,都会得到大致相似的结果。您可以尝试使用自定义复制功能进行一些测试,该功能以比默认系统副本更大的块(例如2MB或5MB)进行读/写,这可能会提高性能。最终,您的磁盘I / O是此处的瓶颈。
答案 6 :(得分:0)
也许你不需要实际上将characer物理地添加到文件中,只是虚拟。可能存在一个文件系统驱动程序,它能够将多个文件(1byte + 40gb)虚拟映射到一个虚拟文件中。
答案 7 :(得分:0)
这是Windows命令行(“DOS”)方式:
将您的1个字符放入prepend.txt
copy /b prepend.txt + myHugeFile fileNameOfCombinedFile
答案 8 :(得分:0)
绝对最高性能的方式似乎是进入扇区级别以及文件的实际存储方式。我不确定操作系统是否会成为一个因素,但目标平台可能,无论如何,我们知道你运行的是有用的。
我认为这是一个明显的选择,这种低级别的东西正是系统编程语言 。
你能告诉我们你最终做了什么,会很有趣。