【问题标题】:Copying a folder from a .jar file从 .jar 文件复制文件夹
【发布时间】:2014-06-27 12:32:40
【问题描述】:

我创建了一个名为 FileCopyFromJAR 的类,它有一个名为 copy 的静态方法。这允许我使用 getResourceAsStream 将文件复制到 JAR 之外:

 public static void copy(String source,String dest) throws IOException{
    try{
        File sourceFile = new File(source);
        File destFile = new File(dest);
        InputStream in = FileCopyFromJAR.class.getResourceAsStream(source);
        OutputStream out = new FileOutputStream(destFile);
        int bufferSize = 1024;
        byte[] buf = new byte[bufferSize];
        int len;
        while ((len = in.read(buf)) > 0){
            out.write(buf,0,len);
        }
        in.close();
        out.close();
    }
    catch(IOException e){
        throw e;
    }
}

在我的代码中,我将通过执行以下操作来调用它(假设 test.txt 在我的 .jar 文件的根目录中):

FileCopyFromJAR.copy("/test.txt","c:\\test.txt");

但是,如果我在文件夹中指定文件夹或文件,则会收到 FileNotFoundException。这两个都返回错误:

FileCopyFromJAR.copy("folder\test.txt","c:\\test.txt");
FileCopyFromJAR.copy("folder", "c:\\folder");

我也尝试过使用各种组合,如 /folder\test.txt 等,但似乎没有任何效果。有没有办法让这项工作发挥作用,还是我必须使用其他方法?

【问题讨论】:

  • 这是我刚刚悬赏的问题的重复,让我试着找到它。
  • @djechlin - 谢谢,那太好了!
  • Copy directory from a jar file 的可能重复项
  • 你试过“文件夹/test.txt”吗?
  • @MadProgrammer 是的,我只是确定了。我试过 FileCopyFromJAR.copy("folder\\test.txt", "c:\\test.txt");我得到一个 NullPointerException。

标签: java jar


【解决方案1】:

我想通了!我翻阅了我的“Core Java Volume 1”第 9 版书,上面写着“请注意,无论系统上实际存储资源文件的目录分隔符如何,都必须始终使用 / 分隔符。” (Horstmann,第 571 页,第 10.1 章 JAR 文件)。

所以这行得通:

FileCopyFromJAR.copy("/folder/test.txt", "c:\\test12.txt");

希望这可以帮助任何人!快把我逼疯了!

【讨论】:

    【解决方案2】:

    根据class.getResourceAsStreamdocumentation:“搜索与给定类关联的资源的规则是通过定义该类的class loader来实现的。”

    然后对于加载器类,我们有:

    作为 String 参数提供给 ClassLoader 中的方法的任何类名必须是由 Java Language Specification 定义的二进制名称。

    有效类名的示例包括:

    "java.lang.String"
    "javax.swing.JSpinner$DefaultEditor"
    "java.security.KeyStore$Builder$FileBuilder$1"
    "java.net.URLClassLoader$3$1"
    

    在委托之前,使用此算法从给定的资源名称构造一个绝对资源名称:

    • 如果名称以 '/' ('\u002f') 开头,则绝对名称 资源是名称中“/”后面的部分。
    • 否则,绝对名称的格式如下:
      modified_pa​​ckage_name/name

    modified_pa​​ckage_name 是这个对象的包名,用 '/' 代替了 '.' ('\u002e')。

    所以你应该使用:

    source = "Package_name" + ".folder.test" //remove the ".txt" from the file
    FileCopyFromJAR.class.getResourceAsStream(source);
    

    【讨论】:

    • 如果我使用“test.txt”并且它位于 .jar 文件的根目录中,它可以工作吗?无论如何,当我使用 FileCopyFromJAR.copy("folder.test","c:\\test12.txt"); 调用静态方法时我仍然得到一个 NullPointerException。这会将 folder.test 传递给静态复制方法中的“源”。
    • @Trinculo 那里...它应该与包名称一起使用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-19
    • 1970-01-01
    • 1970-01-01
    • 2020-06-10
    • 1970-01-01
    相关资源
    最近更新 更多