编写java代码,拷贝特定包下的文件到指定路径,禁止使用IO流读写操作

编写java代码,拷贝特定包下的文件到指定路径,禁止使用IO流读写操作,保证打包可执行jar包,可正常启动jar包
项目结构,普通的java项目工程,如下截图:

img

我的要求和代码如下:
package com.demo;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

/**
 * 
 * 现有结构说明,com.demo包下有个Main类,以及一个dat文件,禁止使用IO流读写这个文件,会改变未知属性!!!
 *
 */
public class Main {
    public static void main(String[] args) {
        // 编写代码,实现以下要求
        /**
         * 1.将com.demo下的dat文件 移动或者拷贝一份到 C:\Program Files 目录下
         * 2.肯定是相对路径的,就是比如导出为可执行的jar包运行,放置其他电脑启动这个jar包,也是可以实现拷贝com.demo下的lic到C:\Program Files目录
         * 3.禁止使用IO流读写这个文件,会改变未知属性!!!
         */

        // 目前我的写法是,可惜无法实现上述要求,或者可尝试调用cmd的复制命令?
        Path source = Paths.get("com/demo/dat");
        Path destination = Paths.get("C:\\Program Files\\dat");
        try {
            Files.copy(source, destination);
        } catch (Exception e) {
            System.out.println("复制文件失败:" + e.getMessage());
        }
        
    }
}

我想要达到的结果:

最终导出是一个可执行的jar包,任何电脑启动,比如
java -jar run.jar包,能实现上述拷贝文件效果,即com.demo下的dat文件 移动或者拷贝一份到 C:\Program Files 目录下

拷贝到c盘下需要你给予权限,c盘是不能随便读写文件的,建议换一个盘试试,jar包运行又不是只能在c盘下才能运行的

方案来自 梦想橡皮擦 狂飙组基于 GPT 编写的 “程秘”


你可以使用 java 的 nio 包来实现拷贝文件,下面是一个示例代码:

import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.PathMatcher;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;

public class FileCopier {
    public static void main(String[] args) throws IOException {
        Path source = FileSystems.getDefault().getPath("com", "demo");
        Path target = FileSystems.getDefault().getPath("C:", "Program Files");
        PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:*.dat");

        Files.walkFileTree(source, new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                if (matcher.matches(file.getFileName())) {
                    Path targetFile = target.resolve(file.getFileName());
                    Files.copy(file, targetFile);
                }
                return FileVisitResult.CONTINUE;
            }
        });
    }
}

在打包成可执行的 jar 包后,你可以在命令行中使用 java -jar run.jar 命令来执行上述代码。请注意,在执行此代码前,你需要确保目标目录已经存在且可写。

你的写法中source的路径不对,需要改成:

// 此方式获得的路径为file:/xxxxxxxxxxxx这种路径是没办法使用的
        URL url = Main.class.getResource("");
        // 此操作去除了file:/
        String path = url.getPath();
        // 将本包内的文件与包路径拼接 注意在代码中不要使用/作为分隔符,使用 File.separator
        File file = new File(path + "dat");
        System.out.println("配置文件的路径为:" + file.getAbsolutePath());
Path source=Path.get(file.getAbsolutePath())

该回答引用ChatGPT
请参考下面的解决方案,如果可行 还请点击 采纳,感谢!
为了实现要求,我们可以使用java的nio包中的Paths和Files类来拷贝文件。
可以参考示例代码:

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public class CopyFiles {
    public static void main(String[] args) {
        String sourcePath = "src/main/java/com/example/packagename";
        String destinationPath = "destination/folder/path";

        Path source = Paths.get(sourcePath);
        Path dest = Paths.get(destinationPath);

        try {
            Files.walk(source)
                 .filter(Files::isRegularFile)
                 .forEach(file -> {
                     try {
                         Files.copy(file, dest.resolve(source.relativize(file)));
                     } catch (Exception e) {
                         e.printStackTrace();
                     }
                 });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}


上面的代码实现了从指定的包(即sourcePath)遍历所有的文件,并将它们复制到指定的目标路径(destinationPath)。

最终,我们可以使用如下命令将编译的class文件打包成可执行的jar包:

jar cvf jarfile.jar com/example/packagename

然后,我们可以在任何电脑上启动jar包,它应该能够正常工作。

参考方法2, 调用 Files.move 方法, 具体如下:

import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
public class MoveFileTest {
    public static void main(String[] args) {
        /**
         * 方法1:移动文件或目录
         */
        File txtFile = new File("F:/file/4spaces.txt");
        File dirFile = new File("F:/file/");
        txtFile.renameTo(new File("F:/4spaces/4spaces.txt"));
        dirFile.renameTo(new File("F:/4spaces/file"));
        /**
         * 方法2:移动文件或目录
         */
        try {
            Files.move(Paths.get("F:/file/4spaces.txt"), Paths.get("F:/4spaces/4spaces.txt"), StandardCopyOption.REPLACE_EXISTING);
            Files.move(Paths.get("F:/file/"), Paths.get("F:/4spaces/file"), StandardCopyOption.REPLACE_EXISTING);
        } catch (IOException e) {
            e.printStackTrace();
        }
        /**
         * 方法3:移动文件或目录
         */
        try {
            FileUtils.moveFile(new File("F:/file/4spaces.txt"), new File("F:/4spaces/4spaces.txt"));
            FileUtils.moveDirectory(new File("F:/file/"), new File("F:/4spaces/file"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
package com.demo;

import java.net.URI;
import java.nio.file.*;
import java.util.Collections;

/**
 *
 * 现有结构说明,com.demo包下有个Main类,以及一个dat文件,禁止使用IO流读写这个文件,会改变未知属性!!!
 *
 */
public class Main {
    public static void main(String[] args) throws Exception {

        URI uri = Main.class.getClass().getResource("/com/demo/dat").toURI();
        System.out.println(uri);
        Path source;
        if("jar".equals(uri.getScheme())){
            final String[] array = uri.toString().split("!");
            final FileSystem fs = FileSystems.newFileSystem(URI.create(array[0]), Collections.emptyMap());
            source= fs.getPath(array[1]);
        }else{
             source  = Paths.get(uri);
        }
        Path destination = Paths.get("C:\\Program Files\\dat");
        try {
            Files.copy(source, destination);
        } catch (Exception e) {
            System.out.println("复制文件失败:" + e.getMessage());
        }
        System.out.println("copy success!");
    }
}

可以使用Java的ProcessBuilder类来实现这个目的:

import java.io.IOException;

public class Main {
    public static void main(String[] args) {
        String[] cmd = {"cmd", "/c", "copy", "com/demo/dat", "C:\\Program Files\\dat"};
        try {
            new ProcessBuilder(cmd).start();
        } catch (IOException e) {
            System.out.println("复制文件失败:" + e.getMessage());
        }
    }
}

可以使用Java的Files类的copy()方法,该方法会使用Java的NIO技术复制文件,不会改变文件的属性。
为了保证相对路径的正确性,需要获取到当前运行程序的路径,并将文件相对路径转换为绝对路径。
下面是一个示例代码:

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public class Main {
    public static void main(String[] args) {
        String currentDirectory = System.getProperty("user.dir");
        Path source = Paths.get(currentDirectory, "com/demo/dat");
        Path destination = Paths.get("C:\\Program Files\\dat");
        try {
            Files.copy(source, destination);
        } catch (Exception e) {
            System.out.println("复制文件失败:" + e.getMessage());
        }
    }
}