首先,我从数据库获取数据时出现问题,占用了太多内存并且失败了。我已经设置-Xmx1500M并且我正在使用滚动ResultSet以便处理。现在我需要从数据中创建一个XML,但我不能把它放在一个文件中。目前,我这样做:
while(rs.next()){
i++;
xmlStringBuilder.append("\n\t<row>");
xmlStringBuilder.append("\n\t\t<ID>" + Util.transformToHTML(rs.getInt("id")) + "</ID>");
xmlStringBuilder.append("\n\t\t<JED_ID>" + Util.transformToHTML(rs.getInt("jed_id")) + "</JED_ID>");
xmlStringBuilder.append("\n\t\t<IME_PJ>" + Util.transformToHTML(rs.getString("ime_pj")) + "</IME_PJ>");
//etc.
xmlStringBuilder.append("\n\t</row>");
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部分,我就会耗尽内存。我想过尝试写一个文件,关闭它,然后打开,但这对我来说不会太多,因为我打开它时必须将文件加载到内存中。
答案 0 :(得分:3)
为什么不将所有数据写入一个文件并使用“append”选项打开文件?如果您要写入文件中的数据,则无需读入文件中的所有数据。
然而,这可能是一个更好的解决方案:
PrintWriter writer = new PrintWriter(new BufferedOutputStream(new FileOutputStream("data.xml")));
while(rs.next()){
i++;
writer.print("\n\t<row>");
writer.print("\n\t\t<ID>" + Util.transformToHTML(rs.getInt("id")) + "</ID>");
writer.print("\n\t\t<JED_ID>" + Util.transformToHTML(rs.getInt("jed_id")) + "</JED_ID>");
writer.print("\n\t\t<IME_PJ>" + Util.transformToHTML(rs.getString("ime_pj")) + "</IME_PJ>");
//...
writer.print("\n\t</row>");
}
writer.close();
BufferedOutputStream将在打印数据之前缓冲数据,如果默认值不符合您的需要,您可以在构造函数中指定缓冲区大小。有关详细信息,请参阅Java API:http://java.sun.com/javase/6/docs/api/。
答案 1 :(得分:3)
您正在将完整文件组装到内存中:您应该做的是将数据直接写入文件。
此外,您可以考虑使用正确的XML API,而不是将XML组合为文本文件。我们提供了一个简短的教程here。
答案 2 :(得分:1)
我从未遇到过这个用例,但我很确定vtd-xml支持大小超过1 GB的xml。值得查看@ http://vtd-xml.sourceforge.net
或者你也可以关注以下所有文章系列@ http://www.ibm.com/developerworks/ “输出大型XML文档”
答案 3 :(得分:0)
好的,所以代码被重写了,我将包括整个操作:
//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<?xml version=\"1.0\" encoding=\"UTF-8\" ?>");
writer.print("\n<PROSTORNE_JEDINICE>");
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<row>");
writer.print("\n\t\t<ID>" + Util.transformToHTML(rs.getInt("id")) + "</ID>");
writer.print("\n\t\t<JED_ID>" + Util.transformToHTML(rs.getInt("jed_id")) + "</JED_ID>");
//etc
writer.print("\n\t</row>");
}
System.out.println("Kraj u : " +Util.nowTime());
}
writer.print("\n</PROSTORNE_JEDINICE>");
但是generateXML部分仍然占用大量内存(如果我猜对了,它会尽可能多地一点一点)并且我不知道如何优化它(使用另一种方式来提供它writer.print函数)?