所以我正在研究GAE项目。我需要查看城市,国家/地区名称和国家/地区代码,以便注册,LBS,等等......
现在我认为将所有信息放在数据存储区中是相当愚蠢的,因为它会被频繁使用,它会毫无理由地吃掉我的数据存储报价,特别是这些列表不会改变,所以它毫无意义在数据存储区中。
现在我有几个选择:
API - 没有付费服务的预算,免费的服务并不完全可靠。
上传可解析文件 - 有利的选项,因为我喜欢数据永远存在的确定性。 所以我从GeoNames获得了所需的文件(如果有人需要,链接包含所有国家/地区的源文件)。每个国家/地区的文件都是常规的UTF-8制表符分隔文件,非常棒。
但是,现在我可以选择如何格式化和访问数据,问题是:
从Java Servlet容器中的静态文件系统地格式化和检索数据的最佳方法是什么?
最好的方法是最快,最少耗费资源的方法。
有效选项:
我知道将国家/地区文件作为Java Enums导入并通过它们的值非常快,但您认为这会影响超出合理限制的内存吗?另一方面,每次我需要访问一条记录时,循环将经历几千行,直到找到所需的记录...逐行读取所以没有内存问题,但是速度非常慢...我有过在Java服务器中解析excel文件的一些经验,大约需要20秒才解析250条记录,大规模,响应时间将超时(毫无疑问),所以XML就像excel一样吗?
非常感谢你们!请提供意见,所有和任何事情都表示赞赏!
答案 0 :(得分:4)
最简单,最快捷的方法是将文件作为静态Web资源文件,在WEB-INF
文件夹下,在应用程序启动时,有一个上下文侦听器将文件加载到内存中。
在内存中,它应该是Map
,从您要搜索的键映射。这将允许您喜欢恒定的访问时间。
内存消耗只有在它真的很大的情况下才有意义。例如,如果您需要多次访问,那么十万条记录就不值得优化。
静态文件应该是纯文本格式或CSV,它们的读取和解析效率最高。不需要XML格式化,因为解析它会很慢。
如果列表非常大,您可以将其分解为多个较小的文件,并且仅在需要时解析这些文件。一个合理的,简单的分区将是按国家/地区划分,但任何其他分区都可以工作(例如根据其名称使用其名称中的前几个字符)。
您还可以考虑在内存中构建此Map
一次,然后将此映射序列化为二进制文件,并将该二进制文件包含为静态资源文件,这样您只需反序列化此Map
并且不需要将其解析/处理为文本文件并自己构建对象。
对数据文件的改进
将静态资源文件作为文本/ CSV文件或序列化映射的替代方法 数据文件将它作为二进制数据文件,您可以在其中创建自己的自定义文件格式。
使用DataOutputStream
,您可以以非常紧凑和有效的方式将数据写入二进制文件。然后,您可以使用DataInputStream
从此自定义文件加载数据。
此解决方案的优点是文件可以少得多(与纯文本/ CSV /序列化映射相比),加载它会快得多(因为DataInputStream
不使用文本中的数字解析例如,它直接读取数字的字节。
答案 1 :(得分:1)
将源数据中的数据保存为XML。在一天开始时,或者当它发生变化时,将其读入内存:这是您唯一一次产生解析成本。然后有两个主要选项:
(a)您的内存中表单仍然是XML树,您使用XPath / XQuery进行查询。
(b)您的内存形式类似于Java HashMap
如果数据非常简单,则(b)可能是最好的,但它只允许您进行一种硬编码的查询。如果数据更复杂或者您有各种可能的查询,那么(a)更灵活。