如何从JAR中提取文件夹

时间:2011-03-21 11:40:13

标签: java

我需要复制一个文件夹,在运行时打包在Jar中。我想通过调用同一文件夹中包含的函数来实现。

我尝试过使用getSystemResource

URL sourceDirUrl = ClassLoader.getSystemResource("sourceDirName"); 
File sourceDir = new File(sourceDirUrl.toURI());

但它不起作用。 我可能必须递归使用getResourceAsStream函数。是否有更优雅/更直接的方式来做到这一点?

如果我必须以递归方式执行此操作:  1.我不想指定硬编码的文件,我想动态地做  2.我不想创建单独的存档。我希望这个资源与处理它的类在同一个Jar中

由于

我最终做了Koziołek在下面提出的建议。虽然我希望有一个更优雅的解决方案,但它看起来像它一样好。

3 个答案:

答案 0 :(得分:5)

使用类加载器无法检索文件夹,因为它不能是类路径的资源。

可能有几种解决方案:

  • 如果您事先知道要查找的文件名,请使用classloader getResource方法逐个检索文件夹的所有资源。
  • 将整个文件夹打包到一个存档中,您可以使用以前的方法从类加载器中检索该文件。
  • 直接解压缩jar以检索包含的文件夹。它需要知道文件系统中jar的精确位置。根据应用程序的不同,这并不总是可行的,并且不可移植。

我最好选择更便携,更灵活的第二种解决方案,但需要为文件夹内容的所有修改重新打包存档。

答案 1 :(得分:2)

Jar是简单的ZIP文件。您可以将java.util.zip。*包用于decompress个文件。

答案 2 :(得分:0)

我遇到了同样的问题,如果您浏览SO,则提出了各种解决方案,通常实施起来并不那么容易。我尝试了其中的几种,最后对我来说最好的是最简单的:

  • 将文件夹内容打包为.zip文件
  • 将.zip文件作为.jar文件中的资源文件
  • 将.zip文件作为资源文件访问并使用ZipInputStream API提取它。

以下是执行此操作的通用方法:

   /**
    * Extract the contents of a .zip resource file to a destination directory.
    * <p>
    * Overwrite existing files.
    *
    * @param myClass     The class used to find the zipResource.
    * @param zipResource Must end with ".zip".
    * @param destDir     The path of the destination directory, which must exist.
    * @return The list of created files in the destination directory.
    */
   public static List<File> extractZipResource(Class myClass, String zipResource, Path destDir)
   {
      if (myClass == null || zipResource == null || !zipResource.toLowerCase().endsWith(".zip") || !Files.isDirectory(destDir))
      {
         throw new IllegalArgumentException("myClass=" + myClass + " zipResource=" + zipResource + " destDir=" + destDir);
      }

      ArrayList<File> res = new ArrayList<>();

      try (InputStream is = myClass.getResourceAsStream(zipResource);
              BufferedInputStream bis = new BufferedInputStream(is);
              ZipInputStream zis = new ZipInputStream(bis))
      {
         ZipEntry entry;
         byte[] buffer = new byte[2048];
         while ((entry = zis.getNextEntry()) != null)
         {
            // Build destination file
            File destFile = destDir.resolve(entry.getName()).toFile();

            if (entry.isDirectory())
            {
               // Directory, recreate if not present
               if (!destFile.exists() && !destFile.mkdirs())
               {
                  LOGGER.warning("extractZipResource() can't create destination folder : " + destFile.getAbsolutePath());
               }
               continue;
            }
            // Plain file, copy it
            try (FileOutputStream fos = new FileOutputStream(destFile);
                    BufferedOutputStream bos = new BufferedOutputStream(fos, buffer.length))
            {
               int len;
               while ((len = zis.read(buffer)) > 0)
               {
                  bos.write(buffer, 0, len);
               }
            }
            res.add(destFile);
         }
      } catch (IOException ex)
      {
         LOGGER.log(Level.SEVERE, "extractZipResource() problem extracting resource for myClass=" + myClass + " zipResource=" + zipResource, ex);
      }
      return res;
   }