我应该如何在java中提取压缩文件夹?

我使用以下代码在Java中提取zip文件。

import java.io.*; import java.util.zip.*; class testZipFiles { public static void main(String[] args) { try { String filename = "C:\\zip\\includes.zip"; testZipFiles list = new testZipFiles( ); list.getZipFiles(filename); } catch (Exception e) { e.printStackTrace(); } } public void getZipFiles(String filename) { try { String destinationname = "c:\\zip\\"; byte[] buf = new byte[1024]; ZipInputStream zipinputstream = null; ZipEntry zipentry; zipinputstream = new ZipInputStream( new FileInputStream(filename)); zipentry = zipinputstream.getNextEntry(); while (zipentry != null) { //for each entry to be extracted String entryName = zipentry.getName(); System.out.println("entryname "+entryName); int n; FileOutputStream fileoutputstream; File newFile = new File(entryName); String directory = newFile.getParent(); if(directory == null) { if(newFile.isDirectory()) break; } fileoutputstream = new FileOutputStream( destinationname+entryName); while ((n = zipinputstream.read(buf, 0, 1024)) > -1) fileoutputstream.write(buf, 0, n); fileoutputstream.close(); zipinputstream.closeEntry(); zipentry = zipinputstream.getNextEntry(); }//while zipinputstream.close(); } catch (Exception e) { e.printStackTrace(); } } } 

显然,由于break语句,这不会提取文件夹树。 我试图使用递归来处理文件夹树但失败了。 有人可以告诉我如何改进此代码来处理文件夹树而不是压缩的单级文件夹。

您可以使用File.mkdirs()来创建文件夹。 尝试更改您的方法,如下所示:

 public static void getZipFiles(String filename) { try { String destinationname = "c:\\zip\\"; byte[] buf = new byte[1024]; ZipInputStream zipinputstream = null; ZipEntry zipentry; zipinputstream = new ZipInputStream( new FileInputStream(filename)); zipentry = zipinputstream.getNextEntry(); while (zipentry != null) { //for each entry to be extracted String entryName = destinationname + zipentry.getName(); entryName = entryName.replace('/', File.separatorChar); entryName = entryName.replace('\\', File.separatorChar); System.out.println("entryname " + entryName); int n; FileOutputStream fileoutputstream; File newFile = new File(entryName); if (zipentry.isDirectory()) { if (!newFile.mkdirs()) { break; } zipentry = zipinputstream.getNextEntry(); continue; } fileoutputstream = new FileOutputStream(entryName); while ((n = zipinputstream.read(buf, 0, 1024)) > -1) { fileoutputstream.write(buf, 0, n); } fileoutputstream.close(); zipinputstream.closeEntry(); zipentry = zipinputstream.getNextEntry(); }//while zipinputstream.close(); } catch (Exception e) { e.printStackTrace(); } } 

另一个选项是commons-compress ,上面链接的站点上有示例代码。

我需要这样做,因为我使用的API需要一个File参数,你无法从JAR中的资源获取。

我发现@Emre的答案没有正常工作。 出于某种原因,ZipEntry跳过了JAR中的一些文件(没有明显的模式)。 我通过使用JarEntry来修复此问题。 上面的代码中还有一个错误,其中zip目录中的文件可以在目录之前枚举,这会导致exception,因为尚未创建目录。

请注意,以下代码取决于Apache Commons实用程序类。

 /** * * Extract a directory in a JAR on the classpath to an output folder. * * Note: User's responsibility to ensure that the files are actually in a JAR. * The way that I do this is to get the URI with * URI url = getClass().getResource("/myresource").toURI(); * and then if url.isOpaque() we are in a JAR. There may be a more reliable * way however, please edit this answer if you know of one. * * @param classInJar A class in the JAR file which is on the classpath * @param resourceDirectory Path to resource directory in JAR * @param outputDirectory Directory to write to * @return String containing the path to the folder in the outputDirectory * @throws IOException */ private static String extractDirectoryFromClasspathJAR(Class classInJar, String resourceDirectory, String outputDirectory) throws IOException { resourceDirectory = StringUtils.strip(resourceDirectory, "\\/") + File.separator; URL jar = classInJar.getProtectionDomain().getCodeSource().getLocation(); //Note: If you want to extract from a named JAR, remove the above //line and replace "jar.getFile()" below with the path to the JAR. JarFile jarFile = new JarFile(new File(jar.getFile())); byte[] buf = new byte[1024]; Enumeration jarEntries = jarFile.entries(); while (jarEntries.hasMoreElements()) { JarEntry jarEntry = jarEntries.nextElement(); if (jarEntry.isDirectory() || !jarEntry.getName().startsWith(resourceDirectory)) { continue; } String outputFileName = FilenameUtils.concat(outputDirectory, jarEntry.getName()); //Create directories if they don't exist new File(FilenameUtils.getFullPath(outputFileName)).mkdirs(); //Write file FileOutputStream fileOutputStream = new FileOutputStream(outputFileName); int n; InputStream is = jarFile.getInputStream(jarEntry); while ((n = is.read(buf, 0, 1024)) > -1) { fileOutputStream.write(buf, 0, n); } is.close(); fileOutputStream.close(); } jarFile.close(); String fullPath = FilenameUtils.concat(outputDirectory, resourceDirectory); return fullPath; }