[英]Unziping a file that contains other Zip Files
我正在嘗試解壓縮包含其他zip文件的文件。 我的嘗試基於以下Java2s代碼: http : //www.java2s.com/Code/Java/File-Input-Output/LoadresourcefromJarfile.htm 。
我唯一的困難是,當條目本身就是一個Jar文件時,如果不先將其寫入臨時文件就無法解壓縮。
這是我在做什么:
public void load(String jarFileName) throws Exception{
ZipFile zf = new ZipFile(jarFileName);
load(zf.entries(),new FileInputStream(jarFileName),zf.size());
}
public void load(Enumeration<? extends ZipEntry> enumeration, InputStream inputStream, int total) throws Exception {
if(enumeration!=null){
while (enumeration.hasMoreElements()) {
ZipEntry ze = (ZipEntry) enumeration.nextElement();
htSizes.put(ze.getName(), new Integer((int) ze.getSize()));
}
}
BufferedInputStream bis = new BufferedInputStream(inputStream);
ZipInputStream zis = new ZipInputStream(bis);
ZipEntry ze = null;
int retrieved=0;
while ((ze = zis.getNextEntry()) != null) {
if (ze.isDirectory()) {
continue;
}
int size = (int) ze.getSize();
if (size == -1 && htSizes.get(ze.getName())!=null) {
size = ((Integer) htSizes.get(ze.getName())).intValue();
}
if(size==-1)
size=total-retrieved;
retrieved+=size;
byte[] b = new byte[(int) size];
int rb = 0;
int chunk = 0;
while (((int) size - rb) > 0) {
chunk = zis.read(b, rb, (int) size - rb);
if (chunk == -1) {
break;
}
rb += chunk;
}
if(ze.getName().endsWith(".jar")){
File f=File.createTempFile("temp", System.nanoTime()+"");
f.deleteOnExit();
FileOutputStream fos= new FileOutputStream(f);
fos.write(b);
fos.close();
load(f.getAbsolutePath());
}
else htJarContents.put(ze.getName(), b);
}
}
我真正想做的是:
public void load(String jarFileName) throws Exception{
ZipFile zf = new ZipFile(jarFileName);
load(zf.entries(),new FileInputStream(jarFileName),zf.size());
}
public void load(Enumeration<? extends ZipEntry> enumeration, InputStream inputStream, int total) throws Exception {
if(enumeration!=null){
while (enumeration.hasMoreElements()) {
ZipEntry ze = (ZipEntry) enumeration.nextElement();
htSizes.put(ze.getName(), new Integer((int) ze.getSize()));
}
}
BufferedInputStream bis = new BufferedInputStream(inputStream);
ZipInputStream zis = new ZipInputStream(bis);
ZipEntry ze = null;
int retrieved=0;
while ((ze = zis.getNextEntry()) != null) {
if (ze.isDirectory()) {
continue;
}
int size = (int) ze.getSize();
if (size == -1 && htSizes.get(ze.getName())!=null) {
size = ((Integer) htSizes.get(ze.getName())).intValue();
}
if(size==-1)
size=total-retrieved;
retrieved+=size;
byte[] b = new byte[(int) size];
int rb = 0;
int chunk = 0;
while (((int) size - rb) > 0) {
chunk = zis.read(b, rb, (int) size - rb);
if (chunk == -1) {
break;
}
rb += chunk;
}
if(ze.getName().endsWith(".jar")){
load(null,new ByteArrayOutputstream(b));
}
else htJarContents.put(ze.getName(), b);
}
}
我看到的第二個版本是,僅當我首先將此內部jar寫入磁盤時,內部jar中包含的條目的大小信息才可用。
有辦法避免這種情況嗎?
非常感謝,克勞斯。
我不知道您在用自己的尺碼做什么,我想您真的把它們弄糊塗了。 ZipInputStream.getNextEntry()將流定位在條目的開頭。 來自http://java.sun.com/javase/6/docs/api/java/util/zip/ZipInputStream.html#getNextEntry()
公共ZipEntry getNextEntry()引發IOException
讀取下一個ZIP文件條目,並將流定位在條目數據的開頭。
因此,以下對我有用:
public void process(String filename) throws IOException {
process(filename, new FileInputStream(new File(filename)));
}
private void process(String filename, InputStream inputStream) throws IOException {
ZipInputStream zis = new ZipInputStream(inputStream);
ZipEntry ze = null;
while ((ze = zis.getNextEntry()) != null) {
if (ze.isDirectory()) {
continue;
}
System.out.println(ze.getName() + " " + ze.getSize());
if (ze.getName().endsWith(".jar")) {
long size = ze.getSize();
byte[] b = new byte[(int) size];
int rb = 0;
int chunk = 0;
while (((int) size - rb) > 0) {
chunk = zis.read(b, rb, (int) size - rb);
if (chunk == -1) {
break;
}
rb += chunk;
}
process(ze.getName(), new ByteArrayInputStream(b));
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.