web-dev-qa-db-ja.com

Java jar内のファイルにアクセスするとJava.nio.file.FileSystemNotFoundExceptionが発生する

Java app)を使用して、jarファイル内のいくつかのファイルを一時ディレクトリにコピーしようとすると、次の例外がスローされます。

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(Unknown Source)
    at com.sora.util.walltoggle.pro.WebViewPresentation.setupTempFiles(WebViewPresentation.Java:83)
   ....

これは私のsetupTempFiles(行番号付き)の小さな部分です:

81. URI uri = getClass().getResource("/webViewPresentation").toURI();
//prints: URI->jar:file:/C:/Users/Tom/Dropbox/WallTogglePro.jar!/webViewPresentation
82. System.out.println("URI->" + uri );
83. Path source = Paths.get(uri);

webViewPresentationディレクトリは、私のjarのルートディレクトリにあります。

enter image description here

この問題は、アプリをjarとしてパッケージ化するときにのみ終了し、Eclipseでのデバッグには問題がありません。これはこれと関係があるのではないかと思われます bug ですが、この問題を修正する方法はわかりません。

感謝します

問題がある場合:

私はJava 8 build 1.8.0-b132をビルドしています

Windows 7 Ult。 x64

44
tom91136

FileSystemNotFoundExceptionは、ファイルシステムを自動的に作成できないことを意味します。ここでは作成していません。

URIを指定すると、_!_に対して分割し、その前の部分を使用してファイルシステムを開き、_!_の後の部分からパスを取得する必要があります。

_final Map<String, String> env = new HashMap<>();
final String[] array = uri.toString().split("!");
final FileSystem fs = FileSystems.newFileSystem(URI.create(array[0]), env);
final Path path = fs.getPath(array[1]);
_

完了したら、.close() your FileSystemする必要があることに注意してください。

51
fge

これはハッキングかもしれませんが、次の方法がうまくいきました。

URI uri = getClass().getResource("myresourcefile.txt").toURI();

if("jar".equals(uri.getScheme())){
    for (FileSystemProvider provider: FileSystemProvider.installedProviders()) {
        if (provider.getScheme().equalsIgnoreCase("jar")) {
            try {
                provider.getFileSystem(uri);
            } catch (FileSystemNotFoundException e) {
                // in this case we need to initialize it first:
                provider.newFileSystem(uri, Collections.emptyMap());
            }
        }
    }
}
Path source = Paths.get(uri);

これは、ZipFileSystemProviderがURIによって開かれたFileSystemsのリストを内部的に保存するという事実を使用しています。

3
fuemf5

IDEまたはリソースが静的でクラスに保存されている場合は動作しません!より良い解決策は Javaで提案されました。リソースフォルダーからファイルを取得するときの.nio.file.FileSystemNotFoundException

InputStream in = getClass().getResourceAsStream("/webViewPresentation");
byte[] data = IOUtils.toByteArray(in);

IOUtilsはApache commons-ioからです。

ただし、既にSpringを使用していてテキストファイルが必要な場合は、2行目を次のように変更できます。

StreamUtils.copyToString(in, Charset.defaultCharset());

StreamUtils.copyToByteArrayも存在します。

2
Kinmarui

Spring Frameworkライブラリを使用している場合、簡単な解決策があります。

要件に従って、webViewPresentationを読みたいです。私は以下のコードで同じ問題を解決できました:

URI uri = getClass().getResource("/webViewPresentation").toURI();
FileSystems.getDefault().getPath(new UrlResource(uri).toString());
0
hemanto