我想解壓縮包含其他zip文件的文件。我的嘗試基於以下Java2代碼:http://www.java2s.com/Code/Java/File-Input-Output/LoadresourcefromJarfile.htm。Unziping包含其他Zip文件的文件
我唯一的困難是,當一個條目本身就是一個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);
}
}
我所看到的機智的第二個版本是大小包含在內部容器中的條目的信息僅在我首先將該內部容器寫入磁盤時纔可用。
有沒有辦法避免這種情況?
非常感謝, 克勞斯。
請用代碼的報價,這使得一切都更具可讀性。 – user29964 2010-07-02 12:39:17
這是你的第一個問題,但你可能已經注意到你的代碼示例看起來很「緊湊」了。您應該查看有關格式化問題的常見問題解答。尤其是具有四個空格的縮進代碼行可以正確格式化它們。 – Stroboskop 2010-07-02 12:41:32
謝謝,我會這樣做的。抱歉給你帶來不便。 – Klaus 2010-07-02 12:46:08