java 从资源文件夹中获取文件时出现java.nio.file.FileSystemNotFoundException
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29746667/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
java.nio.file.FileSystemNotFoundException when getting file from resources folder
提问by Gleeb
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?
似乎没有任何效果。我应该如何构建文件的路径?
回答by Robert
Don't try to access a resource like a file. Just grab the InputStream and read the data from there:
不要尝试访问像文件这样的资源。只需获取 InputStream 并从那里读取数据:
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.
此示例使用 Apache commons-io 库中的 IOUtils 类。
If you are targeting Java 9+ you can alternatively use data = in.readAllBytes?();
.
如果您的目标是 Java 9+,您也可以使用data = in.readAllBytes?();
.
回答by botismarius
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/InputStream 并从那里读取字节。番石榴可以帮助:
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.
另一个可能的解决方案,具有 InputStream 和 apache 的共同点:在 Java中将 InputStream转换为字节数组。
From a byte[], simply use the String constructor to obtain the content as a string.
从 byte[] 中,只需使用 String 构造函数即可获取字符串形式的内容。
回答by isapir
You should get the resource through an InputStream
and not a File
, but there is no need for external libraries.
您应该通过 anInputStream
而不是 a获取资源File
,但不需要外部库。
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
您可以在https://stackoverflow.com/a/5445161/968244 上了解有关该方法的更多信息
回答by naXa
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.
如果使用 Spring,请注入资源。无论是文件,文件夹,甚至是多个文件,都有机会,您可以通过注入来完成。警告:不要使用File
和Files.walk
注入的资源,否则你会FileSystemNotFoundException
在作为 JAR 运行时得到。
This example demonstrates the injection of multiple images located in static/img
folder.
此示例演示了注入位于static/img
文件夹中的多个图像。
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());
}
}
回答by llogiq
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.
您应该使用getResourceAsStream(…)
而不是getResource(…)
. 有多种方法可以将所有字节读入字节数组,例如 Apache Commons 有一个实用方法可以做到这一点。