【发布时间】:2011-10-04 10:47:08
【问题描述】:
我正在尝试通过套接字连接到一台远程服务器,并且我从套接字返回大的 xml 响应,由 '\n' 字符分隔。
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<data>
.......
.......
</data>
</Response>\n <---- \n acts as delimiter
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<data>
....
....
</data>
</Response>\n
..
我正在尝试使用 SAX Parser 解析这些 xml。理想情况下,我想通过搜索 '\n' 来获得对字符串的完整响应,并将此响应提供给解析器。但由于我的单个响应非常大,当我在字符串中保存如此大的 xml 时,我会出现 outOfMemory 异常。所以唯一的选择是将 xml 流式传输到 SAX。
SAXParserFactory spfactory = SAXParserFactory.newInstance();
SAXParser saxParser = spfactory.newSAXParser();
XMLReader xmlReader = saxParser.getXMLReader();
xmlReader.setContentHandler(new MyDefaultHandler(context));
InputSource xmlInputSource = new InputSource(new
CloseShieldInputStream(mySocket.getInputStream()));
xmlReader.parse(xmlInputSource);
我正在使用 closeShieldInputStream 来防止 SAX 由于“\n”而在异常时关闭我的套接字流。我问了previous question ..
现在有时我会遇到解析错误
org.apache.harmony.xml.ExpatParser$ParseException: At line 1, column 8: not well-formed (invalid token)
我搜索了它,found 发现此错误通常发生在实际 xml 的编码与 SAX 所期望的不同时。我写了一个C程序,打印出xml,我所有的xml都是UTF-8编码的。
现在我的问题..
- 上面给出的xml解析错误还有其他原因吗 除了编码问题
- 有什么方法可以将 SAX 的输入打印(或写入任何文件)为 它从套接字流式传输?
在尝试了 Hemal Pandya 的回答之后..
OutputStream log = new BufferedOutputStream(new FileOutputStream("log.txt"));
InputSource xmlInputSource = new InputSource(new CloseShieldInputStream(new
TeeInputStream(mReadStream, log)));
xmlReader.parse(xmlInputSource);
当我挂载 SDCard 时创建了一个名为 log.txt 的新文件,但它是空的。我用对了吗?
最后我是怎么做到的..
我用 TeeInputStream 本身解决了这个问题。感谢 Hemal Pandya 提出的建议。
//open a log file in append mode..
OutputStream log = new BufferedOutputStream(new FileOutputStream("log.txt",true));
InputSource xmlInputSource = new InputSource(new CloseShieldInputStream(new
TeeInputStream(mReadStream, log)));
try{
xmlReader.parse(xmlInputSource);
//flush content in the log stream to file..this code only executes if parsing completed successfully
log.flush();
}catch(SaxException e){
//we want to get the log even if parsing failed..So we are making sure we get the log in either case..
log.flush();
}
【问题讨论】:
-
请看我的编辑,我已经为每个响应添加了一个 doctype 元素。这是第一个错误的原因吗?
-
除了在
try和catch块中调用log.flush(),另一种选择是在outisde 之外进行——try{ xmlReader.parse(xmlInputSource); }catch(SaxException e){ /* log exception */ } log.flush(); -
hmmm...但是在我的情况下,当我遇到异常时,我会直接从异常捕获本身返回..所以在我的情况下这是不可能的
标签: java android sockets stream saxparser