2011-04-21 52 views
0

我在做一个程序来解析来自http的XML文件。 而XML在根标签的前面有一些空间。修剪XML时内存不足错误

所以,我需要在解析它之前修剪XML。

这里是我写的方法,

 private String trimXML(InputStream inputStream){ 
     Writer writer = null; 
     try{ 
      writer = new StringWriter(); 
      char[] buffer = new char[Constants.BUFFER_SIZE]; 
      try { 
       Reader reader = null; 
       try { 
        reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8")); 
        int n = 0;     
        while ((n = reader.read(buffer)) != -1) { 
         writer.write(buffer, 0, n); 
        } 
       } catch (UnsupportedEncodingException e) { 
        e.printStackTrace(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } finally { 
       try { 
        inputStream.close(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
      return writer.toString().trim(); 
     }catch(NullPointerException e){ 
      return null; 
     } 
    } 

现在我面临的一大问题是,我请求XML几次之后,内存不足的错误就是让...

任何人都可以给我一些建议来解决它?

+0

u可以使用DOM解析器? DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance(); \t \t \t \t DocumentBuilder docBuilder = dbfac.newDocumentBuilder(); \t \t \t \t InputStream is = ???; \t \t doc = docBuilder.parse(is); – 2011-04-21 03:20:00

+1

为什么要修剪它?如果您从别处请求xml,则使用SAX解析器在处理它时解析它,而不必在内存中加载完整的XML文档。另外,检查内存泄漏(修剪它后XML引用发生了什么,出于某种原因它们是否在附近?)。 – squawknull 2011-04-21 03:22:14

+0

DOM解析器仍然需要将XML完全加载并映射到内存中,然后才能对其进行解析。 SAX解析器允许在加载流时处理XML。 – squawknull 2011-04-21 03:23:28

回答

1

您正在使用StringWriter,这意味着您将继续将XML文件内容写入内存中的缓冲区。所以,显然,如果最后一个缓冲区保留在内存中而没有垃圾收集,你将会打到OutOfMemory

顺便说一下,我不理解你的程序如何解决你的问题。它只是修整整个文件。这意味着它将从文档的开头和结尾清除空格。

我对你的建议是,你不需要担心空白,并使用StAX或任何适合你的解析文件。如有必要,在解析期间修剪。

但是,冲洗可能有帮助。因此,速战速决,可这一点,

.. 
.. 
String str = writer.toString().trim(); 
writer.flush(); 
return str; 
.. 
.. 

NB:围绕XML元素的空格会被解析器忽略,不过。如果你需要修改一些属性/元素值,那是另一回事。

1

为什么? XML解析器不关心空白。如果你收到一个不解析的XML文档,解决方案是修复发送者,而不是在接收者处搞些东西。这样每个人都是错的。

1

我可以建议,也许你正试图解决已经解决的问题?你需要自己写解析器吗?

我建议不要尝试和自己解析XML,而是使用类似于Android的Simple XML库的库。我刚刚写了一篇博客文章,解释如何将它包含在您的项目中:you can find that here

0

你可以推进的InputStream的 '<' 使用类似的第一次出现:

InputStream inputStream = new BufferedInputStream(YOUR_INPUT_STREAM); 
    byte[] start = "<".getBytes("UTF-8"); 
    byte[] potentialStart = new byte[1]; 

    inputStream.read(potentialStart); 
    while(start[0] != potentialStart[0]) { 
     inputStream.mark(1); 
     inputStream.read(potentialStart); 
    } 
    inputStream.reset();