读取/写入优先级队列到文本文件的有效方法是什么?

时间:2011-09-05 16:47:41

标签: java data-structures file-io

我有一个优先级队列类,我在Java中实现,因为它是一个队列数组。我需要一种好的方法(不使用序列化)在每个“事务”之后记录和存储优先级队列的内容,或者从优先级队列中排队对象()/ dequeue()。如果需要由文本文件中的程序重建优先级队列,它应该作为备份。

我有一些想法和每个问题:

  • 在每个“事务”之后,循环遍历队列,并使用对象之间的分隔符将每个队列写入文件中的一行。 - 我的问题是它需要将所有对象出列并重新入队,这看起来非常低效。

  • 每次入队或出列后,只需编写该对象或从文件中删除该对象即可。 - 我的问题是:如果这是我应该采取的方法,我很难想出一种在出列后轻松找到并删除对象的方法。

任何提示/提示/建议都将不胜感激!

4 个答案:

答案 0 :(得分:1)

要遍历队列,您可以迭代它。这是非破坏性的(但只是松散的线程安全)

每次将队列内容写入磁盘可能会非常慢。对于典型的硬盘驱动器,一个小队列将需要大约20 ms来写入。即最多每秒50次。如果您使用SSD,对于小型队列来说这会快得多,但即使您不使用序列化,您仍然需要编组数据。

另一种方法是使用旨在支持事务,队列和持久性的JMS服务器。典型的JMS服务器每秒可处理大约10,000条消息。有许多好的免费服务器可用。

答案 1 :(得分:1)

我会将您的要求作为日志模式实现。在文件的末尾,追加每个队列及其优先级,追加每个队列。如果您的消息收发服务器崩溃,您可以重播日志文件,并最终得到适当的状态。

显然,您的日志文件会随着时间的推移而变大。要解决这个问题,您需要经常轮换日志文件。为此,请在某个时间点序列化队列,然后开始登录新文件。您甚至可以通过在将数据结构的快照写入磁盘的同时将事务记录到旧日志和新日志来锁定状态(冻结队列请求)来实现此目的。快照完成后,写一个指示到磁盘的指针,您可以删除旧日志。

写入时间和空间为n,重放应该很少并且相对较快。

答案 2 :(得分:0)

在第二种方法中轻松找到对象......我有几个建议::

  1. 您可以使用优先级功能将对象保存在文件中。
  2. 要在不同位置管理新添加的对象,请在文本文件中的每个插入对象之间保留一些空间,并且在插入对象时,可以使用某些指针(如行为)来指定偏移量或其他可以轻松管理的对象。
  3. 使用缓冲区,因为写内容evreytime可能会非常慢。
  4. 如果您仔细使用优先功能,删除将是微不足道的。
  5. 同样在指针指向的小桶中进行排序将非常快,并且您可以通过在一段时间之后压缩所有对象来始终使用垃圾收集类型的行为。

答案 3 :(得分:0)

还有一个建议:(考虑是否一定要使用一个文件):

如果您的对象编号不是很大,请将每个对象存储到单独的文件中。当然,您需要为每个对象创建一个唯一的标识符,您也可以使用此标识符作为文件名。这样,您始终可以根据存储在对象中的标识符添加或删除单个文件。如果对象具有无法修改的各种类,则只需存储将标识符映射到对象的哈希映射。因此,在将对象添加到队列之前,您需要创建一个标识符,然后将该对象和标识符作为一对添加到映射中,并将新文件名写为标识符并包含该对象。我将在删除和重新加载方面做些什么,因为它只不过是练习。

个人而言,我赞成罗伯特哈维在对这个问题的评论中提出的建议。考虑使用数据库,特别是如果你的项目已经有了。这样可以比在文件中定位位置更容易,更快速地存储对象和删除对象。因为即使您在文件中找到对象的位置,很可能您需要再次编写整个文件(仅在没有该对象的情况下)。这与循环没有什么不同。使用数据库,可以避免所有这些麻烦。