【问题标题】:Setting the root context of the created jar file when using JarOutputStream使用 JarOutputStream 时设置创建的 jar 文件的根上下文
【发布时间】:2014-03-21 01:40:18
【问题描述】:

我正在编写一个简短的应用程序,它打开一个 .jar 文件,对其内容运行一些转换,然后再次将其包装为一个 .jar 文件。我正在使用How to use JarOutputStream to create a JAR file? 中的方法来创建新的 jar 文件,它的工作原理是它在新的 jar 文件中创建一个文件层次结构,该文件层次结构一直延伸到我的计算机的根目录。

这是完全合乎逻辑的,因为我将目标目录作为来自计算机根目录的路径传递给进程。我找不到任何 other 方式来传达进程需要能够找到我的目标文件夹的上下文。如何设置要从中创建 .jar 文件的上下文?

澄清一下:

我已经重写了上面链接的解决方案的 Run 方法以接受两个参数:一个定义输出 jar 文件的名称和位置的字符串,以及一个定义我要压缩的文件夹的位置的字符串,如下所示:

public void run(String output, String inputDirectory) throws IOException
{
  JarOutputStream target = new JarOutputStream(new FileOutputStream(output));     
  add(new File(inputDirectory), target, inputDirectory.length());
  target.close();
}

我交给该方法的两个示例值是:C:/temp/964ca469-5f7b-4c56-8b5a-72b4c1c851e0/help.jar 和 C:/temp/964ca469-5f7b-4c56-8b5a-72b4c1c851e0/出/

我希望 .jar 文件的结构在“out”之后的正斜杠处有根,但 .jar 文件的层次结构是:

C:
 |-Temp
     |-964ca469-5f7b-4c56-8b5a-72b4c1c851e0
                                          |-out
                                             |-{content}

我尝试将实际内容之前的字符串长度传递给 Add 方法,并在添加 JarEntry 之前将其删除,但这只会让我出现超出索引的错误,这非常有意义,因为我只是frikkin' 摸索。

在添加文件之前,必须有一种方法可以将 JarEntry 类设置为文件夹层次结构中的特定点,或者有其他方法可以做同样的事情,但到目前为止我还找不到。

谢谢。

【问题讨论】:

  • 你为什么不改用zip filesystem provider
  • 主要原因是我是一个完整的 Java 菜鸟。我会尝试一下,但我想从自我完善的角度来理解我在这里做错了什么;我认为这可能会在接下来的几个月中出现很多。
  • 好吧,如果您是初学者,使用新界面更是一个理由,它更容易使用;)

标签: java jar


【解决方案1】:

JAR 文件中没有“根上下文”。文件和路径是什么完全取决于您放入 JarEntries 的名称。

【讨论】:

  • 嗯。我主要是 XSLT hack,上下文就是一切,所以我很可能只是在这里停留在这个概念上。以下是我对您的回答的不理解:我正在使用资源的完整路径来引起 Jar 进程的注意;如果我不这样做,那么我需要某种方式将 Jar 进程带到资源中。我在这里把我的问题说清楚了吗?现在,我的 Jar 文件中的文件结构一直延伸到计算机的根目录;我想要的是一个从我提供给进程的最后一个目录级别开始的文件系统。
【解决方案2】:

从来没有想过如何创建 Jar 文件,但正如 fge 所建议的那样,zip 文件系统提供程序确实更容易使用。我在我的主要方法中使用了这个:

CreateJarPackage zipper = new CreateJarPackage();

    System.out.println(baseline + unique_directory  + "/" + out_jar_file);
    System.out.println(baseline + unique_directory + "/out/");
    System.out.println(baseline.length() + unique_directory.length() + 5);

    try {
        zipper.addZipFiles(baseline + unique_directory + "/" + out_jar_file, baseline + unique_directory + "/out/", baseline.length() + unique_directory.length() + 5);
    } catch (Throwable e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    File folder = new File(baseline + unique_directory + "/out/");
    File[] listOfFiles = folder.listFiles();

    for (int i = 0; i < listOfFiles.length; i++) {
        if (listOfFiles[i].isDirectory()) {

            try {
                zipper.addZipFiles(baseline + unique_directory  + "/" + out_jar_file, listOfFiles[i].toString(), baseline.length() + unique_directory.length() + 5);
            } catch (Throwable e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }
    }

这样称呼:

import java.io.File;
import java.net.URI;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.HashMap;
import java.util.Map;

public class FinalZipCreator {
public static void processList(URI uri, Map<String, String> env, String path)
        throws Throwable {
    try (FileSystem zipfs = FileSystems.newFileSystem(uri, env)) {
        File folder = new File(path);
        File[] listOfFiles = folder.listFiles();
        int index = path.length();
        for (int i = 0; i < listOfFiles.length; i++) {
            if (listOfFiles[i].isFile()) {
                Path externalTxtFile =Paths.get(listOfFiles[i].toString());
                Path pathInZipfile = zipfs.getPath(listOfFiles[i]
                        .toString().substring(index));
                // copy a file into the zip file
                Files.copy(externalTxtFile, pathInZipfile,
                        StandardCopyOption.REPLACE_EXISTING);
            } else if (listOfFiles[i].isDirectory()) {
                Path externalTxtFile = Paths.get(listOfFiles[i].toString());
                Path pathInZipfile = zipfs.getPath(listOfFiles[i]
                        .toString().substring(index));
                // copy a file into the zip file
                Files.copy(externalTxtFile, pathInZipfile,
                        StandardCopyOption.REPLACE_EXISTING);
                File folder2 = new File(listOfFiles[i].toString());
                File[] listOfFiles2 = folder2.listFiles();
                int index2 = listOfFiles[i].toString().length();
                for (int e = 0; e < listOfFiles2.length; e++) {
                    if (listOfFiles2[i].isFile()) {
                        Path externalTxtFile2 = Paths.get(listOfFiles2[e].toString());
                        Path pathInZipfile2 = zipfs.getPath(listOfFiles2[e]
                                .toString().substring(index2));
                        // copy a file into the zip file
                        Files.copy(externalTxtFile2, pathInZipfile2,
                                StandardCopyOption.REPLACE_EXISTING);
                    }
            }
        }

    }}

}

}

可能有无数更好的方法可以做到这一点,但它确实有效。感谢您的帮助。

附带说明一下,它相当于我在 Jar 创建器中永远找不到的“pathInZipFile”函数。

【讨论】:

    猜你喜欢
    • 2010-11-19
    • 2012-07-10
    • 2014-06-12
    • 2023-03-07
    • 2017-02-09
    • 2014-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多