我即将开始一个项目,我可以预见到需要编辑的大文件(大多数是平面文本文件,但可能是CSV,固定宽度,XML,......)。我需要在应用程序中开发这些部分进行编辑。
在尝试确定处理大量数据(可能进入GB范围)而不必加载整个数据的好方法时,我发现Audacity能够很好地处理大文件。 Audacity是开源的,所以我认为在这种情况下它会成为我的优秀教学工具。但是,我开始思考自己是否经历了代码,现在我完全糊涂了。
我希望这个问题有两个结果:
在不加载整个文件的情况下处理此编辑的好方法。我考虑过在编辑数据时加载数据,并根据需要进行缓存。
Audacity如何做到的解释。
我正在使用C#和.NET,但答案不需要与该环境相关联。
答案 0 :(得分:2)
声音文件基本上是一个数据流,对吗?所以你实际上并不需要立即处理整个文件。 Audacity用户可能只在任何给定时刻使用该大文件的小片段。
假设,如果你要为一个大型声音文件添加1秒的声音片段,你只需要在需要保存时处理整个文件,此时你将3个部分拼接在一起:之前,1秒片段,之后。因此,唯一需要实际记忆的是1秒片段,也可能是片段前后声音的一小部分。
因此,当你保存时,你会一次读取64兆字节的文件(如果你真的很咄咄逼人),并将其传输到临时文件,直到你到达插入点。然后流出1秒的片段,流式传输原始文件的剩余部分,关闭临时写入文件,删除原始文件,并将新文件重命名为原始文件名。
当然,这比这复杂一点。例如,保存前可能会有多个编辑,还有一个撤消缓冲区。但我几乎可以向你保证Audacity在未保存的编辑复杂性方面受限于可用内存量。
答案 1 :(得分:2)
一些技巧可以使编辑更简单,更快。
当用户想要跳转到第X行或时间戳T 时,您不希望浏览整个文件计数换行符和字符。浏览数据,并创建记录。比方说,每50行记录字节偏移,字符数和行号。此数据可以存储在哈希表,树或仅有序列表中。然后,当用户在文件中跳转时,您可以找到最近的索引点并从那里读取,直到找到所请求的点。在使用Unicode时,此技术特别有用,其中每个字符的字节数可能会有所不同。如果文件太大,则完整索引将不适合内存,您可能希望限制索引点并将它们更广泛地分隔,或将索引存储在临时文件中。
正如Harvey所建议的那样 - 只在内存中存储更改(作为差异),然后通过从输入到输出的流式传输将它们应用到文件中。树或有序列表可能会有所帮助,因此您可以快速找到从输入到输出写入时需要进行更改的下一个位置。
如果更改太大而无法容纳在内存中,您可能希望在单独的临时文件中跟踪它们(可能与原始文件位于同一文件夹中)。您可以继续编写连续的更改列表,并在此更改文件中附加新的更改。保存时,您将在删除临时文件之前阅读更改列表并创建要应用的最终更改列表。出于性能原因,避免重写更改日志文件可能会有所帮助;相反,只需附加到它的末尾,并在执行保存时删除冗余或取消编辑。
有趣的事实:您用于更改日志的相同结构可用于提供撤消/重做信息。