java - How to copy resources folder out of jar into program files -


i have spent hours , hours searching answer , can't figure out, trying copy resources folder contains images , data files game working on out of running jar , e:/program files/mtd/ works fine when run out of eclipse, when export jar , try it, nosuchfileexception

`jar installing... file:///c:/users/cam/desktop/mtd.jar/resources file:///e:/program%20files/mtd /resources java.nio.file.nosuchfileexception: c:\users\cam\desktop\mtd.jar\resources         @ sun.nio.fs.windowsexception.translatetoioexception(unknown source)         @ sun.nio.fs.windowsexception.rethrowasioexception(unknown source)         @ sun.nio.fs.windowsexception.rethrowasioexception(unknown source)         @ sun.nio.fs.windowsfileattributeviews$basic.readattributes(unknown sou rce)         @ sun.nio.fs.windowsfileattributeviews$basic.readattributes(unknown sou rce)         @ sun.nio.fs.windowsfilesystemprovider.readattributes(unknown source)         @ java.nio.file.files.readattributes(unknown source)         @ java.nio.file.filetreewalker.walk(unknown source)         @ java.nio.file.filetreewalker.walk(unknown source)         @ java.nio.file.files.walkfiletree(unknown source)         @ java.nio.file.files.walkfiletree(unknown source)         @ me.zacx.mtd.main.game.<init>(game.java:94)         @ me.zacx.mtd.main.game.main(game.java:301)` 

this code using:

    if (!pffolder.exists()) {     pffolder.mkdir();     try {          url url = getclass().getresource("/resources/");         uri uri = null;          if (url.getprotocol().equals("jar")) {             system.out.println("jar");             jarurlconnection connect = (jarurlconnection) url.openconnection();             uri = new uri(connect.getjarfileurl().touri().tostring() + "/resources/");          } else if (url.getprotocol().equals("file")) {             system.out.println("file");             uri = url.touri();         }          final path src = paths.get(uri);         final path tar = paths.get(system.getenv("programfiles") + "/mtd/resources/");          system.out.println("installing...");         system.out.println(src.touri() + " " + tar.touri());          files.walkfiletree(src, new simplefilevisitor<path>() {             public filevisitresult visitfile( path file, basicfileattributes attrs ) throws ioexception {                 return copy(file);             }             public filevisitresult previsitdirectory( path dir, basicfileattributes attrs ) throws ioexception {                 return copy(dir);             }             private filevisitresult copy( path fileordir ) throws ioexception {                 system.out.println("copying " + fileordir.touri() + " " + tar.resolve( src.relativize( fileordir ) ).touri());                 files.copy( fileordir, tar.resolve( src.relativize( fileordir ) ) );                 return filevisitresult.continue;             }         });         system.out.println("done!");     } catch (ioexception e) {         e.printstacktrace();     } catch (urisyntaxexception e) {         e.printstacktrace();     } } 

edited (completely rewritten clarity, example code)

the problem here different file systems. c:/users/cam/desktop/mtd.jar file in windowsfilesystem. since file, , not directory, cannot access subdirectory inside file; c:/users/cam/desktop/mtd.jar/resources valid path if mtd.jar directory instead of file.

in order access on different file system, must use path root of file system. example, if have file in d:\dir1\dir2\file, cannot reach using path begins c:\ (symbolic links not withstanding); must use path starts @ root of file system d:\.

a jar file file. can located anywhere within file system, , can moved, copied or deleted regular file. however, contains within own file system. there no windows path can used reference file inside jar's file system, no path starting @ c:\ can reference file within d:\ file system.

in order access contents of jar, must open jar zipfilesystem.

// autoclose file system @ end of try { ... } block. try(filesystem zip_fs = filesystems.newfilesystem(pathtozipfile, null)) { } 

once have zip_fs, can use zip_fs.getpath("/path/in/zip"); path file within it. path object zipfilesystemprovider path object, not windowsfilesystemprovider path object, otherwise path object can opened, read from, etc., @ least until zipfilesystem closed. biggest differences path.getfilesystem() return zipfilesystem, , resolve() , relativize() cannot use path objects getfilesystem() returns different file systems.

when project ran eclipse, resources in windowsfilesystem, walking file system tree , copying resources straight forward. when project ran jar, resources not in default file system.

here java class copy resources installation directory. work in eclipse (with resources individual files), when application packaged jar.

public class installer extends simplefilevisitor<path> {      public static void installresources(path dst, class<?> cls, string root) throws urisyntaxexception, ioexception {         url location = cls.getprotectiondomain().getcodesource().getlocation();         if (location.getprotocol().equals("file")) {             path path = paths.get(location.touri());             if (location.getpath().endswith(".jar")) {                 try (filesystem fs = filesystems.newfilesystem(path, null)) {                     installresources(dst, fs.getpath("/" + root));                 }             } else {                 installresources(dst, path.resolve(root));             }         } else {             throw new illegalargumentexception("not supported: " + location);         }     }      private static void installresources(path dst, path src) throws ioexception {         files.walkfiletree(src, new installer(dst, src));     }      private final path target, source;      private installer(path dst, path src) {         target = dst;         source = src;     }      private path resolve(path path) {         return target.resolve(source.relativize(path).tostring());     }      @override     public filevisitresult previsitdirectory(path dir, basicfileattributes attrs) throws ioexception {         path dst = resolve(dir);         files.createdirectories(dst);         return super.previsitdirectory(dir, attrs);     }      @override     public filevisitresult visitfile(path file, basicfileattributes attrs) throws ioexception {         path dst = resolve(file);         files.copy(files.newinputstream(file), dst, standardcopyoption.replace_existing);         return super.visitfile(file, attrs);     } } 

called as:

    path dst = paths.get("c:\\program files\\mtd");     installer.installresources(dst, game.class, "resources"); 

Comments