1

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?

Trinculo
  • 1,950
  • 1
  • 17
  • 22

2 Answers2

2

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!

Trinculo
  • 1,950
  • 1
  • 17
  • 22
0

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 '/' ('\u002f'), 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 '.' ('\u002e').

So you should use :

source = "Package_name" + ".folder.test" //remove the ".txt" from the file
FileCopyFromJAR.class.getResourceAsStream(source);
Typo
  • 1,875
  • 1
  • 19
  • 32
  • If I use "test.txt" and it is in the root of the .jar file, it works? In any case, when I called the static method using FileCopyFromJAR.copy("folder.test","c:\\test12.txt"); I still get a NullPointerException. This passes in folder.test to "source" in the static copy method. – Trinculo Jun 26 '14 at 23:27
  • @Trinculo there... it should work with the package name. – Typo Jun 26 '14 at 23:45