问题
I know that it is an easy task, but after changing my code it stopped working and I can't get it back! I use two functions to zip and unzip, even though what it actually does is "jar" and "unjar", but that shouldn't make a huge difference
public static void zipit(File[] infiles, JarOutputStream jos) throws Exception
{
zipit(infiles,"", jos);
}
public static void zipit(File[] infiles, String root, JarOutputStream jos) throws Exception
{
byte[] buffer = new byte[4096];
for(int i=0; i<infiles.length; i++)
{
// recursive call for subfolders... temporary
if(infiles[i].isDirectory())
{
zipit(infiles[i].listFiles(), infiles[i].getName() + "/", jos);
continue;
}
// create string with absolute path
String entryfile = root + infiles[i].getName();
JarEntry entry = new JarEntry(entryfile);
zos.putNextEntry(entry);
FileInputStream fis = new FileInputStream(infiles[i]);
int count;
while((count = fis.read(buffer, 0, buffer.length)) != -1)
zos.write(buffer, 0, count);
}
}
public static void unzipit(File zipfile, File outputfolder) throws Exception
{
JarFile jar = new JarFile(zipfile);
for(Enumeration entries = jar.entries(); entries.hasMoreElements(); )
{
JarEntry entry = (JarEntry) entries.nextElement();
File unzipped = new File(outputfolder, entry.getName());
if (entry.isDirectory() && !unzipped.exists())
{
unzipped.mkdirs();
continue;
}
else if (!unzipped.getParentFile().exists())
unzipped.getParentFile().mkdirs();
FileOutputStream fos = new FileOutputStream(unzipped);
InputStream in = jar.getInputStream(entry);
byte[] buffer = new byte[4096];
int count;
while((count = in.read(buffer, 0, buffer.length)) != -1)
fos.write(buffer, 0, count);
fos.close();
}
}
Any help/suggestions?
The error occurs when creating the JarFile:
java.util.zip.ZipException: error in opening zip file
at java.util.zip.ZipFile.open(Native Method)
at java.util.zip.ZipFile.<init>(ZipFile.java:131)
at java.util.jar.JarFile.<init>(JarFile.java:150)
at java.util.jar.JarFile.<init>(JarFile.java:114)
回答1:
I don't know if this is your problem or not, but it is generally good practice to close each zip entry after you finish writing.
See ZipOutputStream.closeEntry().
In the code that you show, the very last entry in the zip would not be closed. You also don't show where you close the JarOutputStream itself. This could be causing you to create invalid zip files, which would have errors when they are read back in using your other method.
回答2:
Somehow I got it working, apparently it WAS stream-related... thanks for the help, everyone!
class zipper
{
static byte[] buffer = new byte[4096];
public static void unzip(File zipfile, File outputfolder) throws Exception
{
JarFile zip = new JarFile(zipfile);
Enumeration entries = zip.entries();
while(entries.hasMoreElements())
{
JarEntry entry = (JarEntry) entries.nextElement();
File unzipped = new File(outputfolder,entry.getName());
if (entry.isDirectory() && !unzipped.exists())
{
unzipped.mkdirs();
continue;
}
else if (!unzipped.getParentFile().exists())
unzipped.getParentFile().mkdirs();
InputStream in = zip.getInputStream(entry);
FileOutputStream fos = new FileOutputStream(unzipped);
int count;
while((count = in.read(buffer, 0, buffer.length)) != -1)
fos.write(buffer, 0, count);
// clean up
fos.close();
in.close();
}
}
public static void zip(File[] infiles, JarOutputStream jos) throws Exception
{
zip(infiles,"",jos);
// clean up
jos.flush();
jos.close();
}
public static void zip(File[] infiles, String basefolder, JarOutputStream jos) throws Exception
{
for(int i=0; i<infiles.length; i++)
{
if(infiles[i].isDirectory())
{
// recursive call for directories
zip(infiles[i].listFiles(), infiles[i].getName() + File.separator, jos);
continue;
}
String filepath = basefolder + infiles[i].getName();
JarEntry entry = new JarEntry(filepath);
jos.putNextEntry(entry);
FileInputStream fis = new FileInputStream(infiles[i]); // get stream
int count;
while((count = fis.read(buffer, 0, buffer.length)) != -1)
jos.write(buffer, 0, count);
}
}
}
来源:https://stackoverflow.com/questions/4542508/zip-and-unzip-in-java