web-dev-qa-db-fra.com

Java accès aux fichiers dans le bocal provoque Java.nio.file.FileSystemNotFoundException

En essayant de copier certains fichiers de mon fichier jar dans un répertoire temporaire avec mon Java, l'exception suivante est levée:

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)
   ....

et ceci est une petite partie de mon setupTempFiles (avec des numéros de ligne):

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);

le répertoire webViewPresentation réside dans le répertoire racine de mon pot:

enter image description here

Ce problème ne se termine que lorsque j'empaquette mon application en tant que jar, le débogage dans Eclipse n'a aucun problème. Je soupçonne que cela a quelque chose à voir avec cela bug mais je ne sais pas comment corriger ce problème.

Toutes les aides appréciées

Si important:

Je suis sur Java 8 build 1.8.0-b132

Windows 7 Ult. x64

44
tom91136

Un FileSystemNotFoundException signifie que le système de fichiers ne peut pas être créé automatiquement; et vous ne l'avez pas créé ici.

Compte tenu de votre URI, ce que vous devez faire est fractionné par rapport au !, Ouvrez le système de fichiers en utilisant la partie qui le précède, puis récupérez le chemin de la partie après le !:

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]);

Notez que vous devez .close() votre FileSystem une fois que vous en avez terminé.

51
fge

C'est peut-être un hack, mais ce qui suit a fonctionné pour moi:

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);

Cela utilise le fait que ZipFileSystemProvider stocke en interne une liste des systèmes de fichiers ouverts par l'URI.

3
fuemf5

La réponse acceptée n'est pas la meilleure car elle ne fonctionne pas lorsque vous démarrez l'application dans IDE ou que la ressource est statique et stockée dans des classes! Une meilleure solution a été proposée à Java.nio. file.FileSystemNotFoundException lors de l'obtention du fichier à partir du dossier des ressources

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

IOUtils est de Apache commons-io.

Mais si vous utilisez déjà Spring et souhaitez un fichier texte, vous pouvez changer la deuxième ligne en

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

StreamUtils.copyToByteArray existe également.

2
Kinmarui

Si vous utilisez la bibliothèque Spring Framework, il existe une solution simple.

Selon l'exigence, nous voulons lire webViewPresentation; Je pourrais résoudre le même problème avec le code ci-dessous:

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