0

基本上我需要一个文本文件,例如:

弗雷德
·伯尼
·亨利

并能够按顺序从文件中读取它们

亨利·
伯尼·
弗雷德

我正在读取的实际文件> 30MB,读取整个文件,将其拆分为数组,反转数组然后从那里开始,这将是一个不太完美的解决方案。它需要的时间太长了。我的具体目标是找到第一次出现的字符串(在本例中是“InitGame”),然后返回该行开头的位置。

我以前在 python 中做过类似的事情。我的方法是寻找到文件的末尾 - 1024,然后读取行直到我到达末尾,然后从我之前的起点寻找另一个 1024,并且通过使用tell(),当我到达前一个时我会停止初始点。所以我会从文件末尾向后读取这些块,直到找到我正在寻找的文本。

到目前为止,我正在用 Java 做这件事。任何帮助将不胜感激,如果您住在巴尔的摩附近,您甚至可能会得到一些新鲜出炉的饼干。

谢谢!

更多信息:

我需要向后搜索,因为我正在阅读的文件是我托管服务器的游戏的日志文件(它是城市恐怖中的 |err| 服务器。检查一下)。日志文件记录游戏中发生的每个事件,然后我的程序将解析每个事件,对其进行处理,然后对其采取行动(例如,它会跟踪人们的爆头,还会自动踢出正在成为 d-bags 的人)。我需要搜索回最近的 InitGame 条目,以便我可以实例化所有玩家对象并处理自该游戏开始以来需要处理的任何其他内容。文件中有数百个 InitGame 事件,但我想要最后一个。如果有更好的方法不需要向后搜索,请告诉我。

谢谢

4

4 回答 4

1

您可以使用 RandomAccessFile 重复您的 Python 解决方案,并且可能是 LineNumberReader(或只是 Reader)的自定义子类。

于 2010-04-03T16:03:46.860 回答
0

Linux 有一些很棒的文本解析工具,它们可能比尝试在 Java 中更适合。

于 2010-04-03T17:09:42.453 回答
0

在向后搜索时,我想到了两个答案。第一种是向前搜索,并在您到达文件末尾时保留最后找到的 InitGame 文本(并在您读取文件时在另一个 InitGame 出现时覆盖它)。

第二种解决方案是找出文件大小(使用 f.length()),将其分成重叠超过 InitGame 片段最大大小的大块(以避免由于在有趣的地方拆分两个块而导致的问题部分),然后从最后一个开始读取并继续向文件开始(使用 Reader 的 skip() 函数跳转到您想要的读取位置:不需要实际的文件分割)。如果您确定没有有趣的多字节字符,RandomAccessFile 会很有用。

当然,最有效的解决方案是读取输出的日志文件,保留对最后找到的 InitGame 的引用。这样,您将永远不必重新读取相同的数据两次。您甚至可以进行设置,使您的 java 程序每隔几秒唤醒一次,查看文件,并读入新添加的行。

于 2010-04-04T22:47:06.767 回答
0

所以,当我确切地解释我在做什么时,我需要更加详细。基本上我正在编写一个程序来管理我运行的游戏服务器。为了让程序与游戏同步,它需要找到最近的 InitGame 行,然后从那里读取,以便它可以记录从回合开始时它需要的所有命中、杀死、连接和断开连接. 由于日志文件可能非常大(上次我忘记清理它的文本超过 500MB),我不想从前面搜索,而是从后面搜索。在 Java 中没有内置的方法可以做到这一点。在搜索了大量互联网后,我发现了这个: http: //mattfleming.com/node/11. 从那我取出 BackwardsFileInputStream 类并使用它。然后在我的应用程序中,我反转字符。下次我应该能够构建自己的方法,现在我看到了它是如何完成的并且有了更好的理解。

因此,一旦程序从最近的 InitGame 中读取了日志文件,它将模仿 tail -f 并在写入时读取日志文件。

于 2010-04-05T13:28:52.070 回答