Skip to content

Commit

Permalink
Avoid enumerating every jar entry in FileUtil::listResourceDirectory
Browse files Browse the repository at this point in the history
Use 'java.nio.file.FileSystem' in place of 'java.util.jar.JarFile' to
list all the resources under a given classpath (on Windows & Linux), as
that is a bit neater and potentially more efficient than scanning the
entire ZIP directory structure.
  • Loading branch information
stejbac committed Dec 7, 2021
1 parent ec58b26 commit 746061e
Showing 1 changed file with 22 additions and 29 deletions.
51 changes: 22 additions & 29 deletions common/src/main/java/bisq/common/file/FileUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,12 @@
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;

import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLDecoder;

import java.nio.charset.StandardCharsets;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.Paths;

Expand All @@ -37,14 +38,13 @@
import java.io.IOException;
import java.io.InputStream;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import lombok.extern.slf4j.Slf4j;

Expand Down Expand Up @@ -177,38 +177,31 @@ public static void resourceToFile(String resourcePath,
}
}

// adapted from https://stackoverflow.com/questions/3923129/get-a-list-of-resources-from-classpath-directory/48190582#48190582
public static List<String> listResourceDirectory(String directoryName) throws IOException, ResourceNotFoundException {
URL url = Thread.currentThread().getContextClassLoader().getResource(directoryName);
if (url == null) {
throw new ResourceNotFoundException(directoryName);
}
URI uri;
try {
uri = url.toURI();
} catch (URISyntaxException e) {
throw new IOException(e);
}
if (url.getProtocol().equals("file")) {
try {
File dir = new File(url.toURI());
String[] filenames = dir.list();
if (filenames != null) {
return List.of(filenames);
}
} catch (URISyntaxException e) {
throw new IOException(e);
File dir = new File(uri);
String[] filenames = dir.list();
if (filenames != null) {
return List.of(filenames);
}
} else if (url.getProtocol().equals("jar")) {
List<String> filenames = new ArrayList<>();
String dirname = directoryName + "/";
String path = url.getPath();
String jarPath = path.substring(5, path.indexOf("!"));
try (JarFile jar = new JarFile(URLDecoder.decode(jarPath, StandardCharsets.UTF_8.name()))) {
Enumeration<JarEntry> entries = jar.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
String name = entry.getName();
if (name.startsWith(dirname) && !dirname.equals(name)) {
filenames.add(name.substring(dirname.length()));
}
}
try (FileSystem fileSystem = FileSystems.newFileSystem(uri, Collections.emptyMap());
Stream<Path> filePaths = java.nio.file.Files.walk(fileSystem.getPath(directoryName), 1)) { //NOPMD
return filePaths
.skip(1)
.map(path -> path.getFileName().toString())
.collect(Collectors.toUnmodifiableList());
}
return filenames;
}
throw new IOException("Failed to list resource directory: " + directoryName);
}
Expand Down

0 comments on commit 746061e

Please sign in to comment.