是否有一个API来获取类路径的资源(例如,我会从中获取Class.getResource(String) )作为java.nio.file.Path ? 理想情况下,我想用的classpath资源使用花哨的新路径的API。
Answer 1:
这一次对我的作品:
return Paths.get(ClassLoader.getSystemResource(resourceName).toURI());
Answer 2:
猜你想做的事,是对来自类路径的资源调用Files.lines(...) - 从一个罐子内可能。
由于Oracle曲时的路径以不使返回的getResource可用路径,如果它驻留在一个jar文件,你需要做什么路径的概念是这样的:
Stream stream = new BufferedReader(new InputStreamReader(ClassLoader.getSystemResourceAsStream("/filename.txt"))).lines();
Answer 3:
最普遍的解决方案如下:
interface IOConsumer {
void accept(T t) throws IOException;
}
public static void processRessource(URI uri, IOConsumer action) throws IOException {
try {
Path p=Paths.get(uri);
action.accept(p);
}
catch(FileSystemNotFoundException ex) {
try(FileSystem fs = FileSystems.newFileSystem(
uri, Collections.emptyMap())) {
Path p = fs.provider().getPath(uri);
action.accept(p);
}
}
}
主要的障碍是应对两种可能,要么,具有现有的文件系统,我们应该使用,但不会关闭(如使用file的URI或Java 9的模块存储),或不必打开,从而安全地关闭文件系统自己(像ZIP / JAR文件)。
因此,解决上述封装在实际操作interface ,处理这两种情况下,安全地在第二种情况下事后关闭,并努力从Java 7到Java 10.探测是否已经有打开新的前一个开放的文件系统,所以它也可以在您的应用程序的另一个组件已经打开一个文件系统为同一个zip / jar文件的情况。
它可以在上面提到的所有的Java版本,如清单内容的包(可以使用java.lang中的例子)作为Path S,就像这样:
processRessource(Object.class.getResource("Object.class").toURI(), new IOConsumer() {
public void accept(Path path) throws IOException {
try(DirectoryStream ds = Files.newDirectoryStream(path.getParent())) {
for(Path p: ds)
System.out.println(p);
}
}
});
在Java 8或更新版本,你可以使用lambda表达式或方法引用到代表实际的行动,如
processRessource(Object.class.getResource("Object.class").toURI(), path -> {
try(Stream stream = Files.list(path.getParent())) {
stream.forEach(System.out::println);
}
});
做同样的。
爪哇9的模块系统的最终释放打破了上面的代码示例。 该JRE不一致返回路径/java.base/java/lang/Object.class的Object.class.getResource("Object.class")而应该是/modules/java.base/java/lang/Object.class 。 这可以固定通过预先缺失/modules/当父路径被报告为不存在的:
processRessource(Object.class.getResource("Object.class").toURI(), path -> {
Path p = path.getParent();
if(!Files.exists(p))
p = p.resolve("/modules").resolve(p.getRoot().relativize(p));
try(Stream stream = Files.list(p)) {
stream.forEach(System.out::println);
}
});
然后,它会再次与所有版本和存储方法的工作。
Answer 4:
事实证明,你能做到这一点,与内置的帮助Zip文件系统供应商 。 然而,直接传递资源URI来Paths.get将无法正常工作; 相反,必须首先创建的jar URI一个zip文件系统没有条目名称,然后参考该文件系统的条目:
static Path resourceToPath(URL resource)
throws IOException,
URISyntaxException {
Objects.requireNonNull(resource, "Resource URL cannot be null");
URI uri = resource.toURI();
String scheme = uri.getScheme();
if (scheme.equals("file")) {
return Paths.get(uri);
}
if (!scheme.equals("jar")) {
throw new IllegalArgumentException("Cannot convert to Path: " + uri);
}
String s = uri.toString();
int separator = s.indexOf("!/");
String entryName = s.substring(separator + 2);
URI fileURI = URI.create(s.substring(0, separator));
FileSystem fs = FileSystems.newFileSystem(fileURI,
Collections.emptyMap());
return fs.getPath(entryName);
}
更新:
它已经正确地指出,上面的代码中包含了资源泄漏,因为代码打开了一个新的文件系统对象,但永远不会关闭它。 最好的办法是通过一个消费类工人对象,就像霍尔格的答案是怎么做的。 打开ZipFS文件系统只是足够长的工人做任何需要的路径做(只要工人不尝试存储供以后使用Path对象),然后关闭文件系统。
Answer 5:
我写了一个小的辅助方法来读取Paths从你的类资源。 这是很方便的使用,因为它只需要你有你的存储资源,以及资源本身的名称类的参考。
public static Path getResourcePath(Class> resourceClass, String resourceName) throws URISyntaxException {
URL url = resourceClass.getResource(resourceName);
return Paths.get(url.toURI());
}
Answer 6:
您无法从资源的jar文件中创建URI。 你可以简单地将其写入到临时文件,然后使用它(java8):
Path path = File.createTempFile("some", "address").toPath();
Files.copy(ClassLoader.getSystemResourceAsStream("/path/to/resource"), path, StandardCopyOption.REPLACE_EXISTING);
Answer 7:
您需要定义文件系统中提到的JAR文件中读取资源https://docs.oracle.com/javase/8/docs/technotes/guides/io/fsp/zipfilesystemprovider.html 。 我成功读取从下方代码的jar文件资源:
Map env = new HashMap<>();
try (FileSystem fs = FileSystems.newFileSystem(uri, env)) {
Path path = fs.getPath("/path/myResource");
try (Stream lines = Files.lines(path)) {
....
}
}
Answer 8:
阅读使用NIO,从资源文件夹中的文件时,在java8
public static String read(String fileName) {
Path path;
StringBuilder data = new StringBuilder();
Stream lines = null;
try {
path = Paths.get(Thread.currentThread().getContextClassLoader().getResource(fileName).toURI());
lines = Files.lines(path);
} catch (URISyntaxException | IOException e) {
logger.error("Error in reading propertied file " + e);
throw new RuntimeException(e);
}
lines.forEach(line -> data.append(line));
lines.close();
return data.toString();
}
文章来源: java.nio.file.Path for a classpath resource