【问题标题】:Java : How to copy folder with contents from resource and copy to temp directory?Java:如何从资源复制文件夹并复制到临时目录?
【发布时间】:2020-08-10 12:33:17
【问题描述】:

项目结构:

src
|
|--resource
    |
    |--PMD
        |-pmd-bin
            |-test.bat
        |-report
            |-report.xml
    |
    |--staticresource

使用maven-assembly插件,我将资源包含在jar文件中。

由于应用程序将使用 PMD 文件夹,我想在 temp 目录中创建 PMD 文件夹的副本,以便我可以开始读取该 temp 目录中的 bat 文件和其他文件。

问题

jar 加载时,无法读取资源中的 PMD 文件夹。

试过了:

        InputStream pmdFolder = classLoader.getResourceAsStream("PMD");
        InputStreamReader isr = new InputStreamReader(pmdFolder, StandardCharsets.UTF_8);
        BufferedReader br = new BufferedReader(isr);
        List<URL> collect = br.lines().map(l -> "PMD" + "/" + l)
                .map(r -> classLoader.getResource(r))
                .collect(toList());
        Path tempPMDFolder = null;
        Path pmd = Files.createTempDirectory("PMD");
        for (URL url : collect) {
            System.out.println(url.toString());
            createSameTempStructure(url, pmd);
        }

private static void createSameTempStructure(URL url, Path pmd) throws IOException {
    //tempPMDFolder.toFile().deleteOnExit();
    try(final InputStream is = url.openStream()) {
        File file = FileUtils.toFile(url);
        System.out.println("file -> "+file.getName());
        if(file.isDirectory()){
            Path tempPMDFolder = createTempPMDFolder(pmd, file.getName());
            System.out.println("tempPMDFolder -> "+tempPMDFolder.toString());
            FileUtils.copyDirectory(file, tempPMDFolder.toFile());
        } else {
            try (OutputStream outputStream = new FileOutputStream(file)) {
                IOUtils.copy(is, outputStream);
            } catch (IOException e) {
                System.out.println(e.getMessage());
            }
        }
    }
}

这里它只是在 temp 目录中创建 PMD 文件夹,没有任何内容,内部文件和文件夹不会被复制。我们有什么办法可以做到这一点?

【问题讨论】:

  • 您是否尝试在第一行中打开一个文件夹作为输入流?看起来像。但是你应该做类似Files.walk(Paths.get("PMD")) 的事情。这为您提供了一个可以使用的流。
  • PMD 是资源中的一个文件夹,当捆绑在 jar 中时,将无法通过您共享的方法访问。

标签: java file-io


【解决方案1】:

这是我想出的。

将文件夹转换为zip 并将该压缩文件放入资源中。 由于输入流只能读取文件。

InputStream pmdFolder = classLoader.getResourceAsStream("PMD.zip");
Path tempPMDDirectory = Files.createTempDirectory("PMD");

然后将 zip 内容解压缩到临时目录,然后使用整个应用程序。

if (pmdFolder != null) {
    try (ZipInputStream zipInputStream = new ZipInputStream(pmdFolder)) {
        // Extract the zip contents and keep in temp directory
        extract(zipInputStream, tempPMDDirectory.toFile());
    }
}
public static void extract(ZipInputStream zip, File target) throws IOException {
    try {
        ZipEntry entry;

        while ((entry = zip.getNextEntry()) != null) {
            File file = new File(target, entry.getName());

            if (!file.toPath().normalize().startsWith(target.toPath())) {
                throw new IOException("Bad zip entry");
            }

            if (entry.isDirectory()) {
                file.mkdirs();
                continue;
            }

            byte[] buffer = new byte[BUFFER_SIZE];
            file.getParentFile().mkdirs();
            BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file));
            int count;

            while ((count = zip.read(buffer)) != -1) {
                out.write(buffer, 0, count);
            }

            out.close();
        }
    } finally {
        zip.close();
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-25
    • 2018-05-19
    • 1970-01-01
    • 2014-12-12
    • 2013-06-03
    • 1970-01-01
    • 2020-01-20
    相关资源
    最近更新 更多