实时解析大型文本文件(Java)

7

我希望使用Java(1.6.x)解析一个相当大的文本文件,想知道哪种方法被认为是最佳实践?

这个文件的大小可能约为1MB,并且将包含数千个类似以下条目的内容;

Entry
{
    property1=value1
    property2=value2
    ...
}

我首先想到使用正则表达式,但我没有在生产环境中使用Java的经验,所以不确定java.util.regex类有多强大。

更明确一些,我的应用程序将是一个Web应用程序(JSP),它解析所需的文件并显示它检索到的各个值。只有一个文件被解析(它驻留在主机上的第三方目录中)。

该应用程序的使用率相对较低(可能仅有少数用户每天使用几次),但当他们使用它时,检索信息尽快是至关重要的。

此外,在每次解析文件时加载文件时是否需要采取任何预防措施?

有人能推荐一种方法吗?

谢谢


2
你是指实时还是快速?这两者有很大的不同。实时意味着你对每个输入都立即给出答案,而不需要等待更多的输入。这通常比批处理慢。 - Chas. Owens
3
除非你在使用小于64兆内存的机器,否则1兆不再被认为是大容量。 - Chas. Owens
我的意思是快速地 - 我希望从Web UI向服务器发送一个请求,该请求将信号传递给服务器,告知它应解析文件并返回结果(以适当的数据结构形式),然后处理这些结果以在UI中显示。 - Chris McAtackney
9个回答

8
如果数据只有1MB且格式符合你所说,那么你可能过度设计了。除非你的服务器是ZX Spectrum之类的,否则只需使用正则表达式进行解析,将数据放入哈希映射中(并保留在那里),不用担心它。它会占用几兆字节的内存,但没关系...?
更新:为了让你更好地了解性能,我测量了String.split()(使用正则表达式)的性能,结果表明,在一台2GHz的机器上,分割10,000个100个字符的字符串需要毫秒级别的时间(换句话说,大约1MB的数据--实际上更接近2MB,因为String是每个字符2个字节)。显然,这不是你正在执行的操作,但你懂我的意思:情况并不糟糕...

很好 - 这实际上也是我在想的事情 - 如果我在头脑中夸大了这个问题。我想我会按照你所说的去做,看看进展如何。如果性能成为问题,那么我可以回来查看其他答案提出的选项。干杯。 - Chris McAtackney
1
我真的不认为这会是个问题——1MB 的数据量实在太少了。 - Neil Coffey

5
如果文法正确,使用类似GOLD Parsing System的解析器生成器。这样可以指定格式并使用高效解析器获取所需令牌,几乎免费获取错误处理。

4

我想知道为什么这不是XML格式,这样你就可以利用现有的XML工具。我特别考虑SAX,这样你就可以轻松地解析/处理它而无需将其全部存储在内存中。

所以你能把它转换成XML吗?

如果你不能,需要使用解析器,请查看JavaCC


这是第三方日志文件,很不幸我无法控制其格式。 - Chris McAtackney

3

使用Scanner类逐行处理您的文件。我不确定您为什么提到了正则表达式。由于歧义和缺乏对上下文中发生情况的语义控制,正则表达式几乎永远不是任何解析问题的正确答案。


请告诉我们正则表达式如何具有歧义。是的,不同的实现方式会有所不同,但它们都(或多或少)有文档记录并保持一致。对于给定的实现方式,每个表达式都有明确且无歧义的含义。 - Matthew Flaschen
当正则表达式变得复杂时,它们并不像人们所认为的那样工作。真正的解析问题及其解决方案从不使用正则表达式。是否有使用正则表达式编写的编译器? - mP.
1
当人们不太清楚地理解某件事情时,他们经常称之为“模糊不清”;只要给自己一些时间去理解它,这将大大减少努力... - KDjava
@mP说“真正的解析问题永远不会使用正则表达式...使用Scanner类”,这是非常具有讽刺意味的,因为Scanner完全是基于正则表达式构建的。 - Iain

2
您可以使用Antlr解析器生成器来构建一个能够解析您文件的解析器。

1

不回答有关解析的问题...但是您可以在新文件到达时解析文件并生成静态页面。这样,您就不会遇到性能问题...(而且我认为1Mb不是一个很大的文件,所以只要您不同时加载太多文件,就可以将其加载到内存中...)


它是同一个文件,一直在被解析 - 编辑了帖子以澄清这一点。 - Chris McAtackney

1

这似乎是一个足够简单的文件格式,因此您可以考虑使用递归下降解析器。与JavaCC和Antlr相比,它的优点是您可以编写一些简单的方法,获取所需的数据,并且不需要学习解析器生成形式主义。

它的缺点是可能效率较低。递归下降解析器原则上比正则表达式更强大。如果您能为此文件类型想出一个语法,它将为您选择的任何解决方案提供服务。


1

如果你在担心Java正则表达式的限制,不用担心。假设你在合理地编写正则表达式方面是有能力的,性能应该不是问题。特性集也非常丰富--包括我最喜欢的贪婪量词


1

另一种解决方案是进行某种形式的预处理(离线完成或作为cron作业),生成非常优化的数据结构,然后用于服务许多Web请求(无需重新解析文件)。

不过,看起来在这种情况下似乎并不需要。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接