是否可以在不重写的情况下将数据添加到文件中?

时间:2011-01-30 17:18:12

标签: java c++ c file prepend

我处理非常大的二进制文件(每个文件几GB到多TB)。这些文件以旧格式存在,升级需要将标头写入文件的FRONT。我可以创建一个新文件并重写数据,但有时这可能需要很长时间。我想知道是否有更快的方法来完成此升级。该平台仅限于Linux,我愿意使用低级函数(ASM,C,C ++)/文件系统技巧来实现这一目标。初始库是Java,JNI是完全可以接受的。

5 个答案:

答案 0 :(得分:9)

本地没有通用的方法。

也许某些文件系统提供了一些功能来执行此操作(无法对此提供任何提示),但您的代码将依赖于文件系统。


解决方案可以是模拟文件系统:您可以将数据存储在一组文件中,然后提供一些函数来打开,读取和写入数据,就好像它是一个文件。

答案 1 :(得分:4)

听起来很疯狂,但如果可以更改从文件中读取数据的功能,则可以按相反的顺序存储文件数据。在这种情况下,您可以在文件末尾附加数据(以相反的顺序)。这只是一个普遍的想法,所以我不能推荐任何特别的东西。 用于反转当前文件的代码如下所示:

 std::string records;
 ofstream out;
std::copy( records.rbegin(), records.rend(), std::ostream_iterator<string>(out));

答案 2 :(得分:2)

这取决于“文件系统技巧”的含义。如果您愿意使用文件系统的磁盘格式,,您要添加的标头大小是文件系统块大小的倍数,那么您可以编写一个程序,用于直接操作文件系统的磁盘结构(卸载文件系统)。

这个企业虽然听起来很毛茸茸 - 如果你有数百个这样的巨型文件需要处理,它可能是值得的。

答案 3 :(得分:0)

我会使用标准的Linux工具来完成它。 编写另一个应用程序来做它似乎是次优的。

cat headerFile oldFile > tmpFile && mv tmpFile oldFile

答案 4 :(得分:0)

我知道这是一个老问题,但我希望这有助于将来的某些人。与模拟文件系统类似,您只需使用命名管道:

mkfifo /path/to/file_to_be_read
{ echo "HEADER"; cat /path/to/source_file; } > /path/to/file_to_be_read

然后,您针对/path/to/file_to_be_read运行旧程序,输入将为:

HEADER
contents of /path/to/source_file
...

只要程序按顺序读取文件并且不通过缓冲区mmap()rewind(),这将有效。