Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java XML处理-性能问题_Java_Xml_Jaxb_Xml Parsing_Jibx - Fatal编程技术网

Java XML处理-性能问题

Java XML处理-性能问题,java,xml,jaxb,xml-parsing,jibx,Java,Xml,Jaxb,Xml Parsing,Jibx,我有一个大约10mb大小的xml文档。它的结构相对简单,但包含大量二进制数据。我需要从中获取数据并将其保存在db中。 尝试过jaxb metro-工作速度非常慢。 我目前正在为此尝试jibx,但对几个xml文档进行解组将使用所有jvm内存-堆空间错误-数据库已损坏。 也许我应该用别的东西来阅读XML?请给我一些建议 编辑 我的xml表示某种消息,包含“to”、“from”等信息,只包含字符串int和日期。最大的部分是字节[]中的附件,每个附件都有自己的元素。也许可以一个接一个地加载这些? 我真的

我有一个大约10mb大小的xml文档。它的结构相对简单,但包含大量二进制数据。我需要从中获取数据并将其保存在db中。 尝试过jaxb metro-工作速度非常慢。 我目前正在为此尝试jibx,但对几个xml文档进行解组将使用所有jvm内存-堆空间错误-数据库已损坏。 也许我应该用别的东西来阅读XML?请给我一些建议

编辑 我的xml表示某种消息,包含“to”、“from”等信息,只包含字符串int和日期。最大的部分是字节[]中的附件,每个附件都有自己的元素。也许可以一个接一个地加载这些?
我真的不知道我该做什么

我觉得把数据从XML模型转换成Java模型只是为了把它转换成数据库模型完全不对。寻找不通过Java对象就支持XML到数据库的工具——如果您的数据库没有XML导入,请寻找第三方工具。Saxon的XSLT-SQL模块可能无法处理二进制数据,但可能有一些工具可以处理这些数据。

可以使用的最简单方法是DOM(Google中有很多示例)

它预加载所有数据以构建内存中的树结构,因此速度很快,而且由于10MB不是很大,您可以尝试这样做(当然内存中的表示会更大)

此外,DOM是您可以使用的最简单/最容易的API

你可以尝试的另一个图书馆是。它非常轻巧,API看起来像
JAXB
,但它更直观、更简单


如果尝试这些,您仍然觉得需要一些内存需求较少的东西,您可以使用一些基于流的解析器,例如Stax,但API有很大不同,而且我觉得使用Stax有些“困难”

您可以使用Stax,这是快速接收/生成xml的一个很好的答案。它现在是jvm的一部分,使用非常简单。你会喜欢它:-)

问题是,在读取文件时,您可以清楚地管理每个元素和属性。在元素(开始/结束)上执行循环,并轻松访问其属性。它让你精确地知道你想做什么。而且,并非所有内容都像DOM那样加载到内存中

网上有很多教程。这是我在oracle网站上找到的关于它的第一页。
Unludo是正确的,您需要使用STAX来保持这个过程尽可能高效-实际上有5种不同的方法可以在Java中解析XML,我概述了它们的优缺点

任何将整个内容保存在ram(DOM或XPath)中的内容都会占用大量内存。SAX要好得多,但它仍然在命中元素时解析出它们,并将它们交给处理程序实现,而STAX在您请求之前不会解析流外的任何内容;它只会向您发送事件,让您知道它正在查看什么

话虽如此,我创建了STAX的内置ontop,以提供STAX性能和XPath易用性

您可以在感兴趣的文件中定义路径,如:

/message/data -- represents the <message><data>[STUFF HERE]</data></message> path
/message/data——表示[STUFF HERE]路径
然后给解析器所有的路径(基本上是规则),然后给它你想要解析的文件,它为你做所有的脏活,只在找到你想要的东西时调用你的代码

该实现非常高效(我不是开玩笑,我花了几天时间对其进行分析,以使实现的开销低于基本的STAX类,因此它不会增加可测量的开销),而且非常易于使用

注意您说过每条消息附带的字节[]是“单独的文件”,我不确定您在XML解析上下文中的意思;我想我们中的一些人可能会假设您的二进制数据是在XML消息中进行base64编码的,如果不是这样,并且您的每条消息都有辅助的数据有效负载,那么您想要做的是保持低内存使用率,将该数据(一次一块)从网络上直接流到数据库

如果您的数据库不允许流式处理一次插入一段值,并且需要整个字节[]blob,则只需将该字节[]从线路上断开并尽快放入数据库,以保持内存使用率较低;如果这些数据实际上都是1MB的原始数据,那么这很可能会使您的堆崩溃,尤其是在同时存在大量连接的情况下


如果您想分享更多有关impl的数据,我相信我们可以提供建议

但我只需要一些数据。我不需要存储整个xml文档。它是这样的:我接收xml;我需要从一些元素中获得一些值;在简单XML和JAXB(JSR-222)API的复杂性方面并没有太大区别(请参阅)。另外,由于JAXB是JAX-WS(SOAP)和JAX-RS(RESTful)的标准Web服务绑定层,因此JAXB在这些环境中更易于使用。感谢您的建议!但是jaxb不是已经在使用stax了吗?我应该针对什么内存使用?我为我的xml文档分析了jaxb解组,它使用了大约100-150mb的内存;jibx使用量减少25-50%。再次感谢。如果您正确管理实例(即提前释放未添加的实例),则stax将使用很少的内存@emmma1223:老实说,我不知道使用了哪个解析器
JAXB
。我猜它会使用
JAXP
处理器available@Blaise道格汉:谢谢你的链接。我发现
Simple
更容易使用,尤其是在你想转换成
String
你的数据的情况下。但大体上说你是正确。
JAXB
将是标准方法感谢您的建议!我应该尝试woodstox实现还是默认实现?我认为默认实现可以。“不过我不知道伍德斯托克一号。”埃玛1223很高兴你喜欢它。这个自由对我帮助很大;-)谢谢你的回答,里亚德。我要试试你的李