我有兴趣在Java(1.6.x)中解析一个相当大的文本文件,并且想知道哪种方法被认为是最佳实践?
该文件的大小可能约为1Mb,并且将包含数千条条目;
Entry
{
property1=value1
property2=value2
...
}
等
我的第一直觉是使用正则表达式,但我之前没有在生产环境中使用Java的经验,所以我不确定java.util.regex类有多强大。
为了澄清一下,我的应用程序将成为一个Web应用程序(JSP),它解析有问题的文件并显示它检索的各种值。只有一个文件被解析(它驻留在主机上的第三方目录中)。
该应用程序的使用率相当低(可能只有少数用户每天使用它几次),但至关重要的是,当他们使用它时,会尽快检索信息。
此外,每次解析文件时,是否有任何预防措施可以将文件加载到内存中?
有人可以推荐一种方法吗?
由于
答案 0 :(得分:8)
如果它大概是1MB并且按照你说的格式,那么听起来你就是过度工程。
除非您的服务器是ZX Spectrum或其他东西,只需使用正则表达式来解析它,敲击哈希映射中的数据(并将其保留在那里),并且不用担心它。它会占用几兆内存,但那又是什么......?
更新:只是为了让您对性能有一个具体的了解,我对performance of String.split()(使用正则表达式)进行的一些测量表明,在2GHz机器上,它需要毫秒来分割10,000个100个字符的字符串(换句话说,大约1兆字节的数据 - 实际上在纯字节量中接近2MB,因为字符串是每个字符2个字节)。很明显,这不是你正在进行的操作,但你明白我的观点:事情并不是那么糟糕......
答案 1 :(得分:5)
如果它是正确的语法,请使用解析器构建器,例如GOLD Parsing System。这允许您指定格式并使用有效的解析器来获取所需的标记,几乎可以免费获得错误处理。
答案 2 :(得分:4)
我想知道为什么这不是XML,然后你可以利用可用的XML工具。我特别想到SAX,在这种情况下,您可以轻松地解析/处理它而无需将其全部保存在内存中。
那么你可以将它转换为XML吗?
如果您不能,并且需要解析器,请查看JavaCC
答案 3 :(得分:3)
使用Scanner类并一次处理一行文件。我不确定你为什么提到正则表达式。正则表达式几乎永远不是任何解析问题的正确答案,因为在什么情境下发生的模糊性和缺乏语义控制。
答案 4 :(得分:2)
您可以使用Antlr解析器生成器构建一个能够解析文件的解析器。
答案 5 :(得分:1)
没有回答有关解析的问题...但是您可以在新文件到达时解析文件并生成静态页面。所以你没有性能问题...(我认为1Mb不是一个大文件所以你可以在内存中加载它,只要你不同时加载太多文件......)
答案 6 :(得分:1)
这似乎是一个简单的文件格式,因此您可以考虑使用Recursive Descent Parser。与JavaCC和Antlr相比,它的优点是你可以编写一些简单的方法,获得所需的数据,而不需要学习解析器生成器的形式。 它的缺点 - 可能效率较低。递归下降解析器原则上比正则表达式更强。如果您可以为此文件类型提供语法,它将为您提供所选择的任何解决方案。
答案 7 :(得分:1)
如果您想知道Java正则表达式的局限性,请不要担心。假设你有能力制作正则表达式,性能应该不是问题。功能集也非常丰富 - 包括我最喜欢的possessive quantifiers。
答案 8 :(得分:1)
另一种解决方案是进行某种形式的预处理(离线完成或作为cron作业),这会产生非常优化的数据结构,然后用于提供许多Web请求(无需重新解析文件)。
但是,看看有问题的情景,似乎并不需要。