Accesing a file in the Jar archive
Hello, I am new to Java and I have a problem with my program.
I am writing an application that among other things can read text files.
Every thing works fine as long as run the .class
If I pack the application into a .jar executable (with the text files inside)
I can not reach the files any more.
Probably I am doing something wrong during the packing...
//this is the constructor
public Antenna(File fos){
try{
FileReader oos =new FileReader(fos);
BufferedReader filebuf =new BufferedReader(oos);
//I do something with the file
oos.close();
}catch (IOException e){
JOptionPane.showMessageDialog(this,
"File: " + fos +" NOT FOUND","Warning",JOptionPane.ERROR_MESSAGE);}
}
//I use something like this to initialize my class
Ant1 =new Antenna(new File("Curzola.ant"));
When I run my application like .jar (that contains the "Curzola.ant") I get the error unless the file Curzola.ant is external to the jar file in the same directory as the -jar file.
Does someone know what I am getting wrong?
I think it should be easy!!
Thanks
carlo
1. When a file is zipped into a jar file with the application, you should no longer us the File class to access it. Instead you should do something like the following:
InputStream in = obj.getClass().getResourceAsStream("Curzola.ant");
...etc...
//or
URL url = obj.getClass().getResource("Curzola.ant");
...etc...
This code assumes that Cozola.ant and the .class file for obj are in the same folder inside the jar.
2. If the final is elsewhere in the jar, you can use a path:
InputStream in = obj.getClass().getResourceAsStream("/resources/Curzola.ant");
...etc...
This indicates that the file has path /resources/Curzola.ant within the jar.
3. Also, be careful with case in jar files. Even under Windows, Curzola.ant and Curzola.ANT are considered different jar entries.
Thanks I have solved my problem with your help, now I find the file.
I am writing the class so I can change the constructor according to my needs.
I have choosen the FileReader because it is very simple to read a text file line by line.
Using the InputStream is a bit more difficult, do you know a way to read a single line,or I have to write the readLine() method by my self?
Thanks
Carlo
If you want to read a text file line-by-line, BufferedReader is a good choice.
If you have a InputStream, you can use classes from java.io to convert an
input stream into a BufferedReader:
InputStream -> InputStreamReader -> BufferedReader
For example:
void f(InputStream in) throws IOException {
Reader r = new InputStreamReader(in, "ISO-8859-1");
BufferedReader br = new BufferedReader(r);
//use br
}
Some coders would use a different InputStreamReader constructor:
Reader r = new InputStreamReader(in);
But that uses the platform's default charset encoding, and since we are
talking about a file in your jar, you shouldn't assume it's being decoded
on the same platform it was encoded.
Your original code, by the way, used FileReader, which is just a convenience
subclass of InputStreamReader, and your code:
FileReader r = new FileReader(file);
was just shorthand for
InputStream is = new FileInputStream(file);
Reader r = new InputStreamReader(is);
Finally, what objects should your constructor accept? One approach
is to be super flexible and accept many types:
public class Example {
public Example(URL url) throws IOException {
this(url.openStream());
}
public Example(File file) throws IOException {
this(new FileInputStream(file));
}
public Example(InputStream in) throws IOException {
this(new InputStreamReader(in, "ISO-8859-1"));
}
public Example(Reader r) throws IOException {
BufferedReader br = new BufferedReader(r);
//use br
}
}
The other extreme is to accept one basic type. In your case, since you want to read text, is to accept a Reader:
public class Example {
public Example(Reader r) throws IOException {
BufferedReader br = new BufferedReader(r);
//use br
}
}
...and have the calling code do the work of constructing an appropriate reader.