Reputation: 11289
I am getting this error on the following code (note that this does not happen on my local machine, only on my build server):
Files.readAllBytes(Paths.get(getClass().getResource("/elasticsearch/segmentsIndex.json").toURI()), Charset.defaultCharset());
And the exception:
Caused by: java.nio.file.FileSystemNotFoundException: null
at com.sun.nio.zipfs.ZipFileSystemProvider.getFileSystem(ZipFileSystemProvider.java:171)
at com.sun.nio.zipfs.ZipFileSystemProvider.getPath(ZipFileSystemProvider.java:157)
at java.nio.file.Paths.get(Paths.java:143)
I tried to fix it by following this solution; my code now looks like this:
URI segmentsIndexURI = getClass().getResource("/elasticsearch/segmentsIndex.json").toURI();
Map<String, String> env = new HashMap<>();
env.put("create", "true");
FileSystem zipfs = FileSystems.newFileSystem(segmentsIndexURI, env); //exception here
Path segmentsIndexPath = Paths.get(segmentsIndexURI);
I am getting the following exception:
java.lang.IllegalArgumentException: Path component should be '/'
at sun.nio.fs.UnixFileSystemProvider.checkUri(UnixFileSystemProvider.java:77)
at sun.nio.fs.UnixFileSystemProvider.newFileSystem(UnixFileSystemProvider.java:86)
at java.nio.file.FileSystems.newFileSystem(FileSystems.java:326)
at java.nio.file.FileSystems.newFileSystem(FileSystems.java:276)
Nothing seems to work. How am I supposed to build the path to the file?
Upvotes: 15
Views: 27045
Reputation: 42575
Don't try to access a resource like a file. Just grab the InputStream and read the data from there:
byte[] data;
try (InputStream in = getClass().getResourceAsStream("/elasticsearch/segmentsIndex.json")) {
data = in.readAllBytes(); // usable in Java 9+
// data = IOUtils.toByteArray(in); // uses Apache commons IO library
}
This example uses the IOUtils class from Apache commons-io library.
If you are targeting Java 9+ you can alternatively use data = in.readAllBytes();
.
Upvotes: 30
Reputation: 23483
You should get the resource through an InputStream
and not a File
, but there is no need for external libraries.
All you need is a couple of lines of code:
InputStream is = getClass().getResourceAsStream("/elasticsearch/segmentsIndex.json");
java.util.Scanner scanner = new java.util.Scanner(is).useDelimiter("\\A");
String json = scanner.hasNext() ? scanner.next() : "";
You can learn more about that method at https://stackoverflow.com/a/5445161/968244
Upvotes: 3
Reputation: 37916
If you use Spring, inject resources. Be it a file, or folder, or even multiple files, there are chances, you can do it via injection. Warning: DO NOT use File
and Files.walk
with the injected resources, otherwise you'll get FileSystemNotFoundException
when running as JAR.
This example demonstrates the injection of multiple images located in static/img
folder.
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
@Service
public class StackoverflowService {
@Value("classpath:static/img/*")
private Resource[] resources;
private List<String> filenames;
@PostConstruct
void init() {
final Predicate<String> isJPG = path -> path.endsWith(".jpg");
final Predicate<String> isPNG = path -> path.endsWith(".png");
// iterate resources, filter by type and get filenames
filenames = Arrays.stream(resources)
.map(Resource::getFilename)
.filter(isJPG.or(isPNG))
.collect(Collectors.toList());
}
}
Upvotes: 3
Reputation: 14511
You should be using getResourceAsStream(…)
instead of getResource(…)
. There are a number of methods to read all bytes into a byte array, e.g. Apache Commons has a utility method to do just that.
Upvotes: 0
Reputation: 3035
Generally, it is not correct to assume that every resource is a file. Instead, you should obtain the URL/InputStream for that resource and read the bytes from there. Guava can help:
URL url = getClass().getResource("/elasticsearch/segmentsIndex.json");
String content = Resources.toString(url, charset);
Another possible solution, with the InputStream and apache commons: Convert InputStream to byte array in Java .
From a byte[], simply use the String constructor to obtain the content as a string.
Upvotes: 6