0

I have a jar which has a resources folder that contains a folder, let's call it toplevel. toplevel contains another folder, called level1. level1 then contains a list of directories. I'd like to retrieve these directories as java.io.File objects, so that another function can do things with these File objects. With the below example that'd be a List<File> like List{dira, dirb, dirc} How can this be done?


toplevel

---level1

------dir a

------dir b

------dir c
ethereumbrella
  • 83
  • 2
  • 10
  • 1
    A JAR file is just a ZipFile, so you could, in theory, just unzip. *"'d like to retrieve these directories as java.io.File objects"* isn't how Jar files work, as stated, they are zip files, so you need to extract the "file" from the jar or use a `OutputStream` to read it – MadProgrammer Dec 16 '21 at 04:57
  • For [example](https://stackoverflow.com/questions/18758105/how-can-i-count-the-number-of-files-in-a-folder-within-a-jar/18758724#18758724) – MadProgrammer Dec 16 '21 at 04:57
  • @MadProgrammer thanks, what is the path to use in here `jf = new JarFile(new File("dist/ResourceFolderCounter.jar"));` where I don't have a path ending in `.jar` but rather a URI of the jar like `jar:file:....` – ethereumbrella Dec 16 '21 at 05:12
  • @MadProgrammer so you are saying it's not possible to get a List objects from the jar? As in even creating a temporary folder, copying over all the contents of the jar and getting a reference to the dirs in that temp folder as a List ? – ethereumbrella Dec 16 '21 at 05:18
  • Yes, you would have to extract all the files from the jar file if you want a `File` reference – MadProgrammer Dec 16 '21 at 05:53
  • You can't. A directory entry in a zip file is not a `File`. A `File` represents a file name on a file system. – user207421 Feb 25 '22 at 01:03

2 Answers2

1

I would suggest extracting matching entries from the jar file and save to a temporary location to get the java.io.File reference.

Option #1:

If you are reading from a file system, use ZipFile to read the file then use ZipFile.getEntry("zip-path") to get the entry and save using Files.copy

See: ZipEntry to File

Option #2:

If you are reading from an input stream source, use ZipInputStream to read the jar file, then iterate, filter and apply action to matching entries. Each matching entry is coupled with a matching ZipInputStream and you can use those input streams to save them to a temporary location, then create the List<File> reference to hand off to another function.

I wrote a quick example in this repo:

The demo essentially just reads the jar file in the resource folder and finds a single matching zip entry (META-INF/license.txt) and saves it to a file.

enter image description here

See Example Implementation in:

<script src="https://gist.github.com/nfet/27fce2870b8cd42e3337f6a21b8e9711.js"></script>
dev101
  • 353
  • 1
  • 2
  • 9
0

Thanks for the help folks but after much ado, found a solution working atop this previous solution https://stackoverflow.com/a/1529707/9486041 to narrow down to the folders and its contents.

JarURLConnection connection = (JarURLConnection) folderURL.openConnection()
JarFile jar = new JarFile(new File(connection.getJarFileURL().toURI()))
Enumeration enumEntries = jar.entries();
while (enumEntries.hasMoreElements()) {
    JarEntry file = (JarEntry) enumEntries.nextElement();
    if (!file.name.startsWith(path + "/")) {
        continue
    }
    File f = new File(System.getProperty("user.home") + "/tmp" + File.separator + file.getName());
    f.getParentFile().mkdirs()
    
    InputStream is = jar.getInputStream(file); // get the input stream
    FileOutputStream fos = new FileOutputStream(f);
    while (is.available() > 0) {  // write contents of 'is' to 'fos'
        fos.write(is.read());
    }
    fos.close();
    is.close();

}
jar.close()
ethereumbrella
  • 83
  • 2
  • 10