在做项目时遇到这样一个问题:
在用java解析zip文档(提取zip文档中的文本内容)时,如果zip文档里面有xml或是html文档时,那么在解析完里面的一个xml或是html文档时,在进行下一次的getNextEntry()时,就抛出异常。代码如下:
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import XmlExtractBySAX.XmlExtractor;
public class ZipExtract {
public static void main(String[] args) {
ZipExtract zip = new ZipExtract();
StringBuffer text = new StringBuffer();
InputStream is;
try {
is = new FileInputStream("c://test.zip");
int n = zip.getText(is,text);
System.out.println(text);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
/**
*
* @param is
* @param text
* @return
*/
private int getText(InputStream is, StringBuffer text) {
ZipInputStream zipis = new ZipInputStream(is);
ZipEntry zipEntry = null;
try {
while((zipEntry = zipis.getNextEntry())!= null) {
//如果为文件夹
if(zipEntry.isDirectory()) {
continue;
}
//获取文件名字
String fileName = zipEntry.getName();
//判断文件类型,这里只写出解析xml的文档
String fileType = fileName.substring(fileName.indexOf('.'));
if(fileType.equalsIgnoreCase(".xml")) {
XmlExtractor xml = new XmlExtractor();
xml.getText(zipis,text);
}
}
} catch (IOException e) {
e.printStackTrace();
}
return 0;
}
}
报错为:
java.io.IOException: Stream closed
at java.util.zip.ZipInputStream.ensureOpen(Unknown Source)
at java.util.zip.ZipInputStream.getNextEntry(Unknown Source)
at ZipExtractByJDK.ZipExtract.getText(ZipExtract.java:39)
at ZipExtractByJDK.ZipExtract.main(ZipExtract.java:19)
查看跟踪流,发现zip流的参数
在调用解析xml或是解析html的parser函数时
closed 由false变为true;
这个问题,整了我好一阵子。在网上也查了很多资料。也没找出个名堂来。
最近才在我的架构师的指导下,这个问题得到了解决。
解决的办法是当遇到xml和html文件时把zip流分出来,自己也查了java的api看到好像解析器类Parser类中的流就只能用一次,不能重新用,具体什么原因现在还不知道。
下面是我分离流的办法:
//定义一个新的流类,重写InputStream流的抽象方法read()。
class XmlInputStream extends InputStream{
InputStream inputStream = null;
public class XmlInputStream(InputStream is){
this.inputStream = is;
}
//重写InputStream的抽象方法
public int reade(){
retrun inputStream.read();
}
}
替换流部分:
if(fileType.equalsIgnoreCase(".xml")) {
XmlExtractor xml = new XmlExtractor();
xml.getText(new XmlInputStream(zipis),text);
}
这样在解析Xml文档或者html文档时关闭的只是XmlImputStream流而不是ZipInputStream流。从而就不会再出现Stream Close异常了。
好了现在问题得到了解决,在遇到xml或是html文档时,就用zip流来定义这个新的XmlInputStream 流的对象。
再用这个新的流传入xml和html文档的解析类。
那么在解析完xml或html文档时,这个新定义的流不能用了,但是原来的zip流就还能用。这就达到了我们的目的了。那么这个项目中的问题就解决了。