ZipInputStream.read()
将从中读取 x 个字节ZipFileEntry
,解压缩它们并为您提供解压缩的字节。
- 使用此处的任何方法来创建输入/输出流。
- 为您的解析器提供输入/输出流。
InputStream
- 开始将解压缩的数据写入输入/输出流(现在视为
OutputStream
)。
- 因此,您现在正在从 zip 文件中读取数据块,解压缩它们并将它们传递给解析器。
PS:
- 如果 zip 文件包含多个文件,请参阅:从 byte[] (Java) 读取时提取 ZipFile 条目的内容,您必须进行检查,以便知道何时到达条目末尾。
- 我不太了解 SAX 解析器,但假设它会以这种方式解析文件(当以块的形式给出时)。
- - 编辑 - -
这就是我的意思:
import java.io.File;
import java.io.InputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class Main {
static class MyRunnable implements Runnable {
private InputStream xmlStream;
private SAXParser sParser;
public MyRunnable(SAXParser p, InputStream is) {
sParser = p;
xmlStream = is;
}
public void run() {
try {
sParser.parse(xmlStream, new DefaultHandler() {
public void startElement(String uri, String localName, String qName, Attributes attributes)
throws SAXException {
System.out.println("\nStart Element :" + qName);
}
public void endElement(String uri, String localName, String qName) throws SAXException {
System.out.println("\nEnd Element :" + qName);
}
});
System.out.println("Done parsing..");
} catch (Exception e) {
e.printStackTrace();
}
}
}
final static int BUF_SIZE = 5;
public static void main(String argv[]) {
try {
SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();
ZipFile zip = new ZipFile(new File("D:\\Workspaces\\Indigo\\Test\\performance.zip"));
Enumeration<? extends ZipEntry> entries = zip.entries();
while (entries.hasMoreElements()) {
// in stream for parser..
PipedInputStream xmlStream = new PipedInputStream();
// out stream attached to in stream above.. we would read from zip file and write to this..
// thus passing whatever we write to the parser..
PipedOutputStream out = new PipedOutputStream(xmlStream);
// Parser blocks in in stream, so put him on a different thread..
Thread parserThread = new Thread(new Main.MyRunnable(saxParser, xmlStream));
parserThread.start();
ZipEntry entry = entries.nextElement();
System.out.println("\nOpening zip entry: " + entry.getName());
InputStream unzippedStream = zip.getInputStream(entry);
byte buf[] = new byte[BUF_SIZE]; int bytesRead = 0;
while ((bytesRead = unzippedStream.read(buf)) > 0) {
// write to err for different color in eclipse..
System.err.write(buf, 0, bytesRead);
out.write(buf, 0, bytesRead);
Thread.sleep(150); // theatrics...
}
out.flush();
// give parser a couple o seconds to catch up just in case there is some IO lag...
parserThread.join(2000);
unzippedStream.close(); out.close(); xmlStream.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}