如何将大量数据从数据库存储到XML(内存问题)?

首先,我从数据库获取数据时遇到了问题,它占用了太多内存并且失败了。 我已经设置-Xmx1500M并且我正在使用滚动ResultSet来处理这个问题。 现在我需要从数据中创建一个XML,但我不能把它放在一个文件中。 目前,我这样做:

while(rs.next()){ i++; xmlStringBuilder.append("\n\t"); xmlStringBuilder.append("\n\t\t" + Util.transformToHTML(rs.getInt("id")) + ""); xmlStringBuilder.append("\n\t\t" + Util.transformToHTML(rs.getInt("jed_id")) + ""); xmlStringBuilder.append("\n\t\t" + Util.transformToHTML(rs.getString("ime_pj")) + ""); //etc. xmlStringBuilder.append("\n\t"); if (i%100000 == 0){ //stores the data to a file with the name i.xml storeKBR(xmlStringBuilder.toString(),i); xmlStringBuilder= null; xmlStringBuilder= new StringBuilder(); } 

它有效; 我得到12个100 MB的文件。 现在,我想要做的是将所有数据放在一个文件中(我然后压缩),但如果只删除if部分,我就会耗尽内存。 我想过尝试写一个文件,关闭它,然后打开,但这不会让我感觉太多,因为当我打开它时我必须将文件加载到内存中。

为什么不将所有数据写入一个文件并使用“append”选项打开文件? 如果您要写入文件,则无需读入文件中的所有数据。

但是,这可能是一个更好的解决方案:

 PrintWriter writer = new PrintWriter(new BufferedOutputStream(new FileOutputStream("data.xml"))); while(rs.next()){ i++; writer.print("\n\t"); writer.print("\n\t\t" + Util.transformToHTML(rs.getInt("id")) + ""); writer.print("\n\t\t" + Util.transformToHTML(rs.getInt("jed_id")) + ""); writer.print("\n\t\t" + Util.transformToHTML(rs.getString("ime_pj")) + ""); //... writer.print("\n\t"); } writer.close(); 

BufferedOutputStream将在打印之前缓冲数据,如果默认值不符合您的需要,您可以在构造函数中指定缓冲区大小。 有关详细信息,请参阅Java API: http : //java.sun.com/javase/6/docs/api/ 。

您正在将完整文件组装到内存中:您应该做的是将数据直接写入文件。

此外,您可以考虑使用正确的XML API,而不是将XML组合为文本文件。 这里有一个简短的教程。

我从来没有遇到过这个用例,但我很确定vtd-xml支持大小超过1 GB的xml。 值得一试@ http://vtd-xml.sourceforge.net

或者您也可以按照下面的所有文章系列@ http://www.ibm.com/developerworks/ “输出大型XML文档”

好的,所以代码被重写,我将包括整个操作:

 //this is the calling/writing function; I have 8 types of "proizvod" which makes //8 XML files. After an XML file is created, it needs to be zipped by a custom zip class generateXML(tmpParam,queryRBR,proizvod.getOznaka()); writeToZip(proizvod.getOznaka()); //inside writeToZip ZipEntry ze = new ZipEntry(oznaka + ".xml"); FileOutputStream fos = new FileOutputStream(new File(zipFolder + oznaka + ".zip")); ZipOutputStream zos = new ZipOutputStream(fos); zos.putNextEntry(ze); FileInputStream fis = new FileInputStream(new File(zipFolder + oznaka + ".xml")); final byte[] buffer = new byte[1024]; int n; while ((n = fis.read(buffer)) != -1) zos.write(buffer, 0, n); zos.closeEntry(); zos.flush(); zos.close(); fis.close(); // inside generateXML PrintWriter writer = new PrintWriter(new BufferedOutputStream(new FileOutputStream(zipFolder +oznaka + ".xml"))); writer.print("\n"); writer.print("\n"); stmt = cm.getConnection().createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); String q = ""; rs = stmt.executeQuery(q); if(rs != null){ System.out.println("Početak u : " +Util.nowTime()); while(rs.next()){ writer.print("\n\t"); writer.print("\n\t\t" + Util.transformToHTML(rs.getInt("id")) + ""); writer.print("\n\t\t" + Util.transformToHTML(rs.getInt("jed_id")) + ""); //etc writer.print("\n\t"); } System.out.println("Kraj u : " +Util.nowTime()); } writer.print("\n"); 

但是generateXML部分仍然需要大量的内存(如果我猜错了,它会尽可能地一点一点地进行)并且我不知道如何优化它(使用另一种方式来提供writer.printfunction)?