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

[1771 byte] By [CarloSteinera] at [2007-11-26 18:56:08]
# 1

Entries in jar archives are not Files. So if your constructor only accepts a File object as a parameter, you are out of luck. But if it so happens you have another constructor that accepts an InputStream, then you can get one like this:InputStream is = this.getClass().getResourceAsStream("/Curzola.ant");

DrClapa at 2007-7-9 20:34:52 > top of Java-index,Java Essentials,New To Java...
# 2

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.

DrLaszloJamfa at 2007-7-9 20:34:52 > top of Java-index,Java Essentials,New To Java...
# 3

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

CarloSteinera at 2007-7-9 20:34:52 > top of Java-index,Java Essentials,New To Java...
# 4
For your specific question:BufferedReader br = new BufferedReader(new InputStreamReader(is));It would help if you read the tutorial: http://java.sun.com/docs/books/tutorial/essential/io/
DrClapa at 2007-7-9 20:34:52 > top of Java-index,Java Essentials,New To Java...
# 5

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.

DrLaszloJamfa at 2007-7-9 20:34:52 > top of Java-index,Java Essentials,New To Java...
# 6
Yow! So many BC doctors! And me practicing without a license and all...
DrLaszloJamfa at 2007-7-9 20:34:53 > top of Java-index,Java Essentials,New To Java...
# 7
Thanks very much for the help. Building my class I will follow your suggestions.\V/_ CarLo
CarloSteinera at 2007-7-9 20:34:53 > top of Java-index,Java Essentials,New To Java...