![](/img/trans.png)
[英]java.nio.file.FileSystemNotFoundException when getting file from resources folder
[英]Getting FileSystemNotFoundException from ZipFileSystemProvider when creating a path to a resource
我有一個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
。 我之前使用過這些說明來創建資源的路徑。 為什么我現在得到例外?
您需要先創建文件系統,然后才能訪問zip中的路徑
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
如果您打算讀取資源文件,可以直接使用getClass.getResourceAsStream
。 這將隱含地設置文件系統。 如果找不到您的資源,該函數將返回null
,否則您將直接擁有一個輸入流來解析您的資源。
擴展@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();
除了@Uwe Allner和@mvreijn:
小心URI
。 有時候, URI
有一個錯誤的格式(例如"file:/path/..."
,正確的人會"file:///path/..."
),你不能得到適當的FileSystem
。
在這種情況下,它有助於從Path
的toUri()
方法創建URI
。
在我的例子中,我稍微修改了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();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.