在任意位置编辑的基于文本的文件的高效设计?
Posted
技术标签:
【中文标题】在任意位置编辑的基于文本的文件的高效设计?【英文标题】:Efficient design for a text-based file that is edited at arbitrary positions? 【发布时间】:2012-10-11 06:08:35 【问题描述】:我正在尝试开发一个允许实时协作的简单在线编辑器(用 Java 编写)。在这个编辑器中,我希望客户能够在任意点编辑源代码(例如,将字母“d”添加到源代码文件的第 11 行第 20 列)。我不确定如何以有效的方式设计这些源代码文件对象,同时仍然允许逐个字母的客户端-服务器同步(类似于 Google Docs 的工作方式)。
我考虑过使用 RandomAccessFile,但在阅读了this post 之后,我认为这不是一种有效的方法。在文件开头附近插入一个字母将涉及更改其后的所有内容。
我目前的计划是使用 StringBuilder 对象及其插入/删除/追加方法来表示服务器和客户端上的源文件。在服务器端,此 StringBuilder 将根据需要转换为实际文件。
我很好奇是否有更好的方法来解决这个问题。有什么想法吗?
【问题讨论】:
您可以使用一个内存数据块,即文件(已备份而不是丢失数据),然后不时将其写回文件(可能带有修订扩展名回滚)。 【参考方案1】:您将需要像 Ropes 这样的东西作为基本数据结构。这将启用 O(log n) 编辑、插入、追加、连接等,因此您无需担心在大型数据结构中间进行编辑。
需要考虑的两个开源库:
Java 的绳索:http://ahmadsoft.org/ropes/ 我自己的不可变“文本”数据结构实现:https://github.com/mikera/mikera/blob/master/src/main/java/mikera/persistent/Text.java除此之外,您还需要构建用于合并和发布同步更改的逻辑。这实际上是棘手的部分:您需要决定解决冲突等的逻辑以及如何将“增量”传输给客户端。
我会将持久性/复制到永久存储视为一个单独的问题 - 最好首先让所有内容与内存数据结构一起正常工作。然后,您可以定期将数据刷新到持久存储中。我建议像 Git 这样的东西,或者如果你特别喜欢冒险,你可以尝试像 Datomic 这样的东西(它本质上是一个像 Git 一样工作的数据库,并保留所有更新的历史记录)
【讨论】:
听起来正是我想要的。以前从不知道绳索/绳索,所以谢谢。 现在管理更改的计划是让来自客户端的所有任务(插入/删除/等)通过服务器上的单线程 ExecutorService。在服务器处理完任务后,它将并行(使用多线程 ExecutorService)将结果输出到各个客户端。我希望设计将足够有效,以防止客户出现明显的滞后。此外,我们实际上计划使用 Git 进行持久存储(尽管 Datomic 听起来很酷)。【参考方案2】:也许更好的方法是使用像Git 这样的分布式版本控制。 用户保存存储库的本地副本,他们可以从远程拉取将在本地合并,提交将更改本地存储库并推送以更新远程。 这意味着您需要用户的权限才能将文档保存在他们的本地机器上。
【讨论】:
Git 很棒,但这种使用模式并不真正符合问题中提出的“在线编辑器”的要求。以上是关于在任意位置编辑的基于文本的文件的高效设计?的主要内容,如果未能解决你的问题,请参考以下文章