我遇到了大约20-30 MB(650000行)的XML文件循环问题。
这是我的元代码:
<cffile action="READ" ile="file.xml" variable="usersRaw">
<cfset usersXML = XmlParse(usersRaw)>
<cfset advsXML = XmlSearch(usersXML, "/advs/advuser")>
<cfset users = XmlSearch(usersXML, "/advs/advuser/user")>
<cfset numUsers = ArrayLen(users)>
<cfloop index="i" from="1" to="#numUsers#">
... some selects...
... insert...
<cfset advs = annunciXml[i]["vehicle"]>
<cfset numAdvs = ArrayLen(advs)>
<cfloop index="k" from="1" to="#numAdvs#">
... insert... or ... update...
</cfloop>
</cfloop>
xml文件的结构是(是的,不是很好: - )
<advs>
<advuser>
<user>
</user>
<vehicle>
<vehicle>
</advuser>
</advs>
在大约120,000行后,我收到一个错误:“内存不足”。
如何改善脚本的性能?
如何诊断最大内存消耗量?
答案 0 :(得分:10)
这大致就是你为你的例子做的事情:
<cfset fis = createObject("java", "java.io.FileInputStream").init(
"#getDirectoryFromPath(getCurrentTemplatePath())#/file.xml"
)>
<cfset bis = createObject("java", "java.io.BufferedInputStream").init(fis)>
<cfset XMLInputFactory = createObject("java", "javax.xml.stream.XMLInputFactory").newInstance()>
<cfset reader = XMLInputFactory.createXMLStreamReader(bis)>
<cfloop condition="#reader.hasNext()#">
<cfset event = reader.next()>
<cfif event EQ reader.START_ELEMENT>
<cfswitch expression="#reader.getLocalName()#">
<cfcase value="advs">
<!--- root node, do nothing --->
</cfcase>
<cfcase value="advuser">
<!--- set values used later on for inserts, selects, updates --->
</cfcase>
<cfcase value="user">
<!--- some selects and insert --->
</cfcase>
<cfcase value="vehicle">
<!--- insert or update --->
</cfcase>
</cfswitch>
</cfif>
</cfloop>
<cfset reader.close()>
答案 1 :(得分:2)
orangepips提供了合理的解决方案。请查看Ben Nadel在ColdFusion中处理非常大的XML文件的解决方案。我已经在一个包含120万行的50MB XML文件上测试了他的方法。 Ben使用类似于orangepips在这里提供的方法 - 使用Java流式传输,然后使用XMLParse ColdFusion中的每个节点来获取货物。看看它 - 就像Ben Nadel的大部分代码和教程一样,它只是有效。
http://www.bennadel.com/blog/1345-Ask-Ben-Parsing-Very-Large-XML-Documents-In-ColdFusion.htm
答案 2 :(得分:1)
我认为Cold Fusion XML Parser使用DOM Parsing,它不适合这种文件大小。您应该尝试找到一个事件驱动的SAX解析器。也许这个链接会有所帮助 http://coldfusion.sys-con.com/node/236002
答案 3 :(得分:1)
我不知道ColdFusion,但20-30Mb并不超出构建内存树的技术范围;许多人经常在200Mb文件上运行XSLT转换。
转向SAX解析听起来像一个极端的措施 - 它是一个如此低级别的界面。