简体   繁体   中英

Copying a folder from a .jar file

I created a class called FileCopyFromJAR that has a static method called copy. This allows me to copy files to outside of the JAR by using getResourceAsStream:

 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;
    }
}

Inside my code, I will call this by doing something like (this assumes test.txt is in the root of my .jar file):

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

However, I get a FileNotFoundException if I specify a folder or a file inside a folder. Both of these return an error:

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

I've also tried using various combinations like /folder\\test.txt, etc. but nothing seems to work. Is there a way to make this work or do I have to use a different method?

I figured it out! I broke out my "Core Java Volume 1" 9th edition book and it says "Note that you must always use / separator, regardless of the directory separator on the system that actually stores the resource files." (Horstmann, page 571, chapter 10.1 JAR Files).

So this works:

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

Hope this helps anyone out there! It was driving me crazy!

According to the class.getResourceAsStream documentation : "The rules for searching resources associated with a given class are implemented by the defining class loader of the class. "

And then for loader class we have:

Any class name provided as a String parameter to methods in ClassLoader must be a binary name as defined by the Java Language Specification .

Examples of valid class names include:

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

Before delegation, an absolute resource name is constructed from the given resource name using this algorithm:

  • If the name begins with a '/' ('\/'), then the absolute name of the resource is the portion of the name following the '/'.
  • Otherwise, the absolute name is of the following form:
    modified_package_name/name

Where the modified_package_name is the package name of this object with '/' substituted for '.' ('\.').

So you should use :

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM