创建路径资源时获得FileSystemNotFoundException从ZipFileSystemProvider

问题描述 投票:29回答:4

我有一个Maven项目和方法内我想创建一个在我的资源文件夹的目录路径。这是这样完成的:

try {
    final URI uri = getClass().getResource("/my-folder").toURI();
    Path myFolderPath = Paths.get(uri);
} catch (final URISyntaxException e) {
    ...
}

生成的URI看起来像jar:file:/C:/path/to/my/project.jar!/my-folder

堆栈跟踪是如下:

Exception in thread "pool-4-thread-1" java.nio.file.FileSystemNotFoundException
    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)

URI似乎是有效的。前!点生成的JAR文件,并在它后面的文件的根目录my-folder的两个部分。我已经使用这个指令之前创建的路径我的资源。为什么我现在得到一个例外?

java maven
4个回答
47
投票

您需要创建文件系统之前,你可以在压缩中访问的路径类似

final URI uri = getClass().getResource("/my-folder").toURI();
Map<String, String> env = new HashMap<>(); 
env.put("create", "true");
FileSystem zipfs = FileSystems.newFileSystem(uri, env);
Path myFolderPath = Paths.get(uri);

这不是自动完成的。

http://docs.oracle.com/javase/7/docs/technotes/guides/io/fsp/zipfilesystemprovider.html


9
投票

如果你打算读取资源文件,可以直接使用getClass.getResourceAsStream。这将implictly建立文件系统。该函数返回null如果你的资源无法找到,否则你直接有一个输入流来解析你的资源。


6
投票

扩展在@Uwe Allner的出色答卷,使用故障安全的方法是

private FileSystem initFileSystem(URI uri) throws IOException
{
    try
    {
        return FileSystems.getFileSystem(uri);
    }
    catch( FileSystemNotFoundException e )
    {
        Map<String, String> env = new HashMap<>();
        env.put("create", "true");
        return FileSystems.newFileSystem(uri, env);
    }
}

与URI调用此您将加载将确保文件系统处于工作状态。我总是叫FileSystem.close()使用后:

FileSystem zipfs = initFileSystem(fileURI);
filePath = Paths.get(fileURI);
// Do whatever you need and then close the filesystem
zipfs.close();

4
投票

除了@Uwe Allner和@mvreijn:

小心的URI。有时URI有一个错误的格式(例如"file:/path/..."和正确的人会"file:///path/..."),你不能得到适当的FileSystem。 在这种情况下,它可以帮助该URIPathtoUri()方法创建的。

在我来说,我修改initFileSystem方法一点点,在非特殊情况下使用的FileSystems.newFileSystem(uri, Collections.emptyMap())。在特殊情况下,使用FileSystems.getDefault()

在我的情况下,也有必要赶IllegalArgumentException处理与Path component should be '/'的情况。在Windows和Linux异常被捕获,但FileSystems.getDefault()工作。在OSX上也不例外情况和newFileSystem创建:

private FileSystem initFileSystem(URI uri) throws IOException {
    try {
        return FileSystems.newFileSystem(uri, Collections.emptyMap());
    }catch(IllegalArgumentException e) {
        return FileSystems.getDefault();
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.