Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/eclipse/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/selenium/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何将resources文件夹从jar复制到程序文件中_Java_Eclipse_File_Program Files - Fatal编程技术网

Java 如何将resources文件夹从jar复制到程序文件中

Java 如何将resources文件夹从jar复制到程序文件中,java,eclipse,file,program-files,Java,Eclipse,File,Program Files,我花了好几个小时寻找答案,但我就是想不出答案,我正试图将我的资源文件夹从运行的jar中复制出来,其中包含我正在制作的游戏的所有图像和数据文件 E:/Program Files/mtd/当我在eclipse中运行它时,它工作得很好,但是当我导出jar并尝试它时,我没有得到任何文件异常 `JAR Installing... file:///C:/Users/Cam/Desktop/mtd.jar/resources to file:///E:/Program%20Files/mtd /resourc

我花了好几个小时寻找答案,但我就是想不出答案,我正试图将我的资源文件夹从运行的jar中复制出来,其中包含我正在制作的游戏的所有图像和数据文件 E:/Program Files/mtd/当我在eclipse中运行它时,它工作得很好,但是当我导出jar并尝试它时,我没有得到任何文件异常

`JAR
Installing...
file:///C:/Users/Cam/Desktop/mtd.jar/resources to file:///E:/Program%20Files/mtd
/resources
java.nio.file.NoSuchFileException: C:\Users\Cam\Desktop\mtd.jar\resources
        at sun.nio.fs.WindowsException.translateToIOException(Unknown Source)
        at sun.nio.fs.WindowsException.rethrowAsIOException(Unknown Source)
        at sun.nio.fs.WindowsException.rethrowAsIOException(Unknown Source)
        at sun.nio.fs.WindowsFileAttributeViews$Basic.readAttributes(Unknown Sou
rce)
        at sun.nio.fs.WindowsFileAttributeViews$Basic.readAttributes(Unknown Sou
rce)
        at sun.nio.fs.WindowsFileSystemProvider.readAttributes(Unknown Source)
        at java.nio.file.Files.readAttributes(Unknown Source)
        at java.nio.file.FileTreeWalker.walk(Unknown Source)
        at java.nio.file.FileTreeWalker.walk(Unknown Source)
        at java.nio.file.Files.walkFileTree(Unknown Source)
        at java.nio.file.Files.walkFileTree(Unknown Source)
        at me.Zacx.mtd.main.Game.<init>(Game.java:94)
        at me.Zacx.mtd.main.Game.main(Game.java:301)`
`JAR
安装。。。
file:///C:/Users/Cam/Desktop/mtd.jar/resources 到file:///E:/Program%20Files/mtd
/资源
java.nio.file.NoSuchFileException:C:\Users\Cam\Desktop\mtd.jar\resources
位于sun.nio.fs.WindowsException.translateToIOException(未知源)
位于sun.nio.fs.WindowsException.rethrowAsIOException(未知源)
位于sun.nio.fs.WindowsException.rethrowAsIOException(未知源)
位于sun.nio.fs.WindowsFileAttributeViews$Basic.readAttributes(未知Sou)
(rce)
位于sun.nio.fs.WindowsFileAttributeViews$Basic.readAttributes(未知Sou)
(rce)
位于sun.nio.fs.WindowsFileSystemProvider.readAttributes(未知源)
位于java.nio.file.Files.readAttributes(未知源)
位于java.nio.file.FileTreeWalker.walk(未知源)
位于java.nio.file.FileTreeWalker.walk(未知源)
位于java.nio.file.Files.walkFileTree(未知源)
位于java.nio.file.Files.walkFileTree(未知源)
atme.Zacx.mtd.main.Game.(Game.java:94)
at me.Zacx.mtd.main.Game.main(Game.java:301)`
这是我正在使用的代码:

    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() + " to " + 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() + " to " + 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();
    }
}
如果(!pfFolder.exists()){
pfFolder.mkdir();
试一试{
URL URL=getClass().getResource(“/resources/”);
URI=null;
if(url.getProtocol().equals(“jar”)){
System.out.println(“JAR”);
JarURLConnection connect=(JarURLConnection)url.openConnection();
uri=新uri(connect.getJarFileURL().tori().toString()+“/resources/”;
}else if(url.getProtocol().equals(“文件”)){
System.out.println(“文件”);
uri=url.toURI();
}
最终路径src=Path.get(uri);
最终路径tar=Path.get(System.getenv(“ProgramFiles”)+“/mtd/resources/”;
System.out.println(“安装…”);
System.out.println(src.toUri()+“到”+tar.toUri());
walkFileTree(src,新的SimpleFileVisitor(){
公共文件VisitResult visitFile(路径文件,基本文件属性属性属性)引发IOException{
返回副本(文件);
}
公共文件VisitResult preVisitDirectory(路径目录,基本文件属性属性属性)引发IOException{
返回副本(dir);
}
私有文件VisitResult复制(路径文件服务器)引发IOException{
System.out.println(“复制”+fileorder.toUri()+“到”+tar.resolve(src.relatize(fileorder)).toUri());
copy(fileorder,tar.resolve(src.relative(fileorder));
返回FileVisitResult.CONTINUE;
}
});
System.out.println(“完成!”);
}捕获(IOE异常){
e、 printStackTrace();
}捕获(URISyntaxException e){
e、 printStackTrace();
}
}

这里的问题是不同的文件系统
C:/Users/Cam/Desktop/mtd.jar
窗口文件系统中的
文件。因为它是一个文件,而不是一个目录,所以您不能访问文件中的子目录
C:/Users/Cam/Desktop/mtd.jar/resources
仅当
mtd.jar
实际上是目录而不是文件时才是有效的
路径

为了访问其他文件系统上的内容,必须使用该文件系统根目录中的路径。例如,如果您在
D:\dir1\dir2\file
中有一个文件,则无法使用以
C:\
开头的路径访问该文件(不支持符号链接);必须使用从该文件系统的根开始的路径
D:\

jar文件只是一个文件。它可以位于文件系统中的任何位置,并且可以像任何常规文件一样移动、复制或删除。但是,它本身包含自己的文件系统。没有windows路径可用于引用jar文件系统中的任何文件,就像从
C:\
开始的路径不能引用
D:\
文件系统中的任何文件一样

要访问jar的内容,必须以
ZipFileSystem
打开jar

// Autoclose the file system at end of try { ... } block.
try(FileSystem zip_fs = FileSystems.newFileSystem(pathToZipFile, null)) {
}
一旦有了
zip_fs
,就可以使用
zip_fs.getPath(“/path/in/zip”)
获取其中文件的
路径。此
Path
对象实际上将是一个
ZipFileSystemProvider
路径对象,而不是
WindowsFileSystemProvider
路径对象,但在关闭
ZipFileSystem
之前,它是一个可以打开、读取等的
Path对象。最大的区别是
path.getFileSystem()
将返回
ZipFileSystem
,并且
resolve()
relative()
不能使用路径对象,其中
getFileSystem()
返回不同的文件系统

当您的项目从Eclipse运行时,所有资源都在
WindowsFileSystem
中,因此遍历文件系统树并复制资源是很简单的。当项目从jar运行时,资源不在默认文件系统中

下面是一个Java类,它将资源复制到安装目录。它将在Eclipse中工作(所有资源都作为单独的文件),并且在应用程序打包到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);
    }
}

这比我想象的要难,但这里是如何做到的

这是我的复制方法参考

请注意图中Jar文件的项目结构

现在我需要读取Jar文件。这个我
    Path dst = Paths.get("C:\\Program Files\\mtd");
    Installer.installResources(dst, Game.class, "resources");
public void copyFile(String inputPath, String outputPath ) throws IOException
{

    InputStream inputStream = null;

    OutputStream outputStream = null;
    try {

        inputStream =  getClass().getResourceAsStream(inputPath);
        outputStream = new FileOutputStream(outputPath);

        byte[] buf = new byte[1024];

        int bytesRead;

        while ((bytesRead = inputStream.read(buf)) > 0) {

            outputStream.write(buf, 0, bytesRead);

       }

    }
    finally {


        inputStream.close();

        outputStream.close();

    }
public static void main(String[] args) throws IOException {
    // TODO Auto-generated method stub

    final String pathPartOne = "test/com";
    final String pathPartTwo = "/MyResources";
    String pathName = "C:\\Users\\Jonathan\\Desktop\\test.jar";

    JarTest test = new JarTest();

    final File jarFile = new File(pathName);

    if(jarFile.isFile()) {  // Run with JAR file
        final JarFile jar = new JarFile(jarFile);
        final Enumeration<JarEntry> entries = jar.entries(); //gives ALL entries in jar
        while(entries.hasMoreElements()) {
            final String name = entries.nextElement().getName();

            if (name.startsWith(pathPartOne+pathPartTwo + "/")) { //filter according to the path
                if(name.contains("."))//has extension
                {
                    String relavtivePath = name.substring(pathPartOne.length()+1);
                    String fileName = name.substring(name.lastIndexOf('/')+1);
                    System.out.println(relavtivePath);
                    System.out.println(fileName);
                    test.copyFile(relavtivePath, "C:\\Users\\Jonathan\\Desktop\\" + fileName);
                }

            }
        }
        jar.close();
    } 


}
 `  
              //on startup
               installDir("");
                for (int i = 0; i < toInstall.size(); i++) {
                    File f = toInstall.get(i);
                    String deepPath = f.getPath().replace(f.getPath().substring(0, f.getPath().lastIndexOf("resources") + "resources".length() + 1), "");
                    System.out.println(deepPath);
                    System.out.println("INSTALLING: " + deepPath);
                    installDir(deepPath);
                    System.out.println("INDEX: " + i);
                }

public void installDir(String path) {
            System.out.println(path);
            final URL url = getClass().getResource("/resources/" + path);
            if (url != null) {
                try {
                    final File apps = new File(url.toURI());
                    for (File app : apps.listFiles()) {
                        System.out.println(app);
                            System.out.println("copying..." + app.getPath() + " to " + pfFolder.getPath());
                            String deepPath = app.getPath().replace(app.getPath().substring(0, app.getPath().lastIndexOf("resources") + "resources".length() + 1), "");
                            System.out.println(deepPath);

                        try {

                                File f = new File(resources.getPath() + "/" + deepPath);
                                if (getExtention(app) != null) {
                                FileOutputStream resourceOS = new FileOutputStream(f);
                                byte[] byteArray = new byte[1024];
                                int i;
                                InputStream classIS = getClass().getClassLoader().getResourceAsStream("resources/" + deepPath);
                        //While the input stream has bytes
                                while ((i = classIS.read(byteArray)) > 0) 
                                {
                        //Write the bytes to the output stream
                                    resourceOS.write(byteArray, 0, i);
                                }
                        //Close streams to prevent errors
                                classIS.close();
                                resourceOS.close();
                                } else {
                                    System.out.println("new dir: " + f.getPath() + " (" + toInstall.size() + ")");
                                    f.mkdir();
                                    toInstall.add(f);
                                    System.out.println(toInstall.size());
                                }
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                } catch (URISyntaxException ex) {
                    // never happens
                }
            }

        }`