How to extract a folder from JAR

后端 未结 3 1866
天命终不由人
天命终不由人 2021-01-18 03:56

I need to copy a folder, packed in a Jar on runtime. I want to do it by calling a function in a class which is also contained in the same folder.

I\'ve tried using <

相关标签:
3条回答
  • 2021-01-18 04:32

    I had the same problem, there are various solutions proposed if you browse SO, usually not so simple to implement. I tried several of them and finally the best for me was the simplest:

    • pack the folder content in a .zip file
    • put the.zip file as a resource file in the .jar
    • access the .zip file as a resource file and extract it using the ZipInputStream API.

    Here a generic method to do this:

       /**
        * 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;
       }
    
    0 讨论(0)
  • 2021-01-18 04:36

    Jar is simple ZIP file. You can use java.util.zip.* package to decompress files.

    0 讨论(0)
  • 2021-01-18 04:40

    Using the classloader you cannot retrieve a folder as it can not be a resource of your classpath.

    Several solutions are possible:

    • Using the classloader getResource method, retrieve all resources of your folder one by one if you know in advance the file names you are looking for.
    • Pack your complete folder into an archive that you can retrieve from the classloader using the previous method.
    • Unzip your jar directly to retrieve the contained folder. It requires to know the precise location of the jar from the filesystem. This is not always possible depending on the application and is not portable.

    I would preferably going for the second solution that is more portable and flexible but requires to repack the archive for all modifications of the folder content.

    0 讨论(0)
提交回复
热议问题