【问题标题】:Editing large data files编辑大型数据文件
【发布时间】:2010-01-12 00:08:15
【问题描述】:

我即将开始一个项目,我可以预见其中有需要编辑的大文件(主要是平面文本文件,但可能是 CSV、固定宽度、XML 等)。我需要开发组件以在应用程序中进行此编辑。

在尝试确定一种无需加载整个数据来处理编辑大量数据(可能进入 GB 范围)的好方法时,我发现 Audacity 能够很好地处理大文件。 Audacity 是开源的,所以我认为在这种情况下它对我来说是一个很好的教学工具。但是,我开始在循环中思考自己的代码,现在我完全糊涂了。

我希望这个问题有两个结果:

  1. 无需加载整个文件即可处理此编辑的好方法。我考虑在他们编辑数据时加载数据,按需缓存。

  2. Audacity 是如何做到的。

我正在使用 C# 和 .NET,但答案不需要耦合到那个环境。

【问题讨论】:

  • 处理大文件的策略确实取决于文件格式,最好知道你在计划什么,它是什么类型的数据(可能是音频数据)?
  • 在 Windows 上,您可以简单地将文件映射到地址空间中的某个位置。只要文件大小不大于您实际处理的大小,您就可以像这样处理它,让操作系统分页代码处理内存管理。
  • EmEditor 非常适合处理大文本文件,如果您正在寻找编辑器。或者这是你想以编程方式做的事情?如果是这样,您将进行哪些类型的编辑,以及对什么进行编辑?
  • @Anon - 你也可以在 posix 系统上使用 mmap() - en.wikipedia.org/wiki/Mmap
  • @fatcat:我需要以编程方式进行。编辑将在一个伞式应用程序中完成。 @Seth:我现在可以肯定的是,它将是要编辑的文本文件。至于里面的格式,我被告知我需要“保持灵活”。我希望提出一个可以全面应用的通用算法。我的猜测是他们倾向于 XML。

标签: editing large-files


【解决方案1】:

几个技巧可以让编辑更简单、更快捷。

  1. 索引它以加快访问速度。当用户什么都不做时,浏览文件并创建一个索引,以便您可以快速找到文件中的特定位置(见下文)。
  2. 仅存储用户所做的更改。在用户保存之前不要尝试将它们直接应用到文件中。
  3. 设置用户跳转到某个点时读入内存的限制。最初读取一两个屏幕的数据以便您可以显示它,然后如果用户没有立即跳转到新位置,请在当前位置之前和之后读取一点。

索引:

当用户想要跳转到 line Xtimestamp T 时,您不想浏览整个文件并计算换行符和字符。浏览数据,并创建记录。比如说,每 50 行,记录字节偏移量、字符数和行号。这些数据可以存储在哈希表、树或只是一个有序列表中。然后当用户在文件中跳转时,您可以找到最近的索引点并从那里读取,直到找到请求的点。这种技术在使用 Unicode 时特别​​有用,其中每个字符的字节数可能会有所不同。如果文件太大,内存中无法容纳完整索引,您可能需要限制索引点并将它们分隔得更宽,或者将索引存储在临时文件中。

编辑和修改大文件:

正如 Harvey 所建议的那样 - 仅将 更改 存储在内存中(作为差异),然后在通过从输入到输出的流式传输保存时将它们应用到文件中。树或有序列表可能会有所帮助,因此您可以在从输入写入输出时快速找到下一个需要进行更改的地方。

如果更改太大而无法放入内存,您可能希望在单独的临时文件中跟踪它们(可能与原始文件位于同一文件夹中)。您可以继续编写一个连续的更改列表,并将新的更改附加到此更改文件中。保存时,您将通读更改列表并创建要应用的更改的最终列表,然后再删除临时文件。出于性能原因,避免重写更改日志文件可能会有所帮助;相反,只需附加到它的末尾,并在执行保存时删除多余的或取消的编辑。

有趣的事实:您用于更改日志的相同结构可用于提供撤消/重做信息。

【讨论】:

  • 我正在想象更改日志可能充当撤消列表,然后您在最后确认了它。感谢您提供非常全面的答案!
【解决方案2】:

声音文件基本上是一个数据流,对吧?因此,您实际上不需要一次处理整个文件。 Audacity 用户在任何给定时刻只能使用该大文件的一小部分 sn-p。

假设,如果你在一个大的声音文件中添加一个 1 秒的 sn-p 声音,你实际上只需要在必须保存时处理整个文件,此时你将 3 个部分拼接在一起:之前, 1 秒 sn-p 及之后。所以真正需要在内存中的只有 1 秒的 sn-p,可能还有 sn-p 前后的一小部分声音。

因此,当您保存时,您一次读取 64 兆字节的文件(如果您真的很激进的话),然后将其流式传输到一个临时文件,直到您到达插入点。然后你把1秒sn-p流出来,把原文件剩下的部分流出来,关闭临时写文件,删除原文件,把新文件重命名为原文件名。

当然,比这复杂一点。例如,在保存之前可能有多个编辑,以及一个撤消缓冲区。但我几乎可以向您保证,Audacity 在未保存的编辑复杂性方面受到可用 RAM 数量的限制。

【讨论】:

  • 如果我可以将已接受答案的功劳分成,我一定会给你一些。
  • 问题编辑部分的好答案——你当然赢得了我的支持。将更改保存在内存中的问题的一种解决方案是在磁盘上保留一个仅追加的更改日志(或更改日志)。当您的更改日志超出内存或新更改使旧更改无效时,您将它们写入磁盘更改日志。如果您定期将所有未写入的更改从内存写入日志文件,您还可以使用它来提供针对程序崩溃的安全性。最终结果将类似于日志结构的文件系统。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-14
相关资源
最近更新 更多