How to deploy files in JAR? - java

I have some method which read some data from the file (actually, it is the bus time).
public void readData(String number) throws IOException{
InputStream fis;
BufferedReader br;
String line;
fis = new FileInputStream("n" + number);
br = new BufferedReader(new InputStreamReader(fis, Charset.forName("UTF-8")));
while ((line = br.readLine()) != null) {
list.add(new Time(line));
}
br.close();
}
And I have my files into project with needed info.
But! (I am writing in Intellij IDEA, but deploying in Eclipse)
When I deploy project, my program doesn't see the files.
What should I do?
Is thinking about
fis = RaspFrame.class.getClassLoader().getResourceAsStream("n" + number);
Right?

"Is thinking about:
fis = RaspFrame.class.getClassLoader().getResourceAsStream("n" + number);
correct?"
Yes. That is (roughly speaking) the way to open a stream to a resource held in a JAR file on your classpath.
(Your existing code is actually reading the files from the file system. It is presumably working from within your IDE because copies of the files are held in the IDE project directory, and the IDE is making the project directory is the "current directory" when you run the program.)

Related

Reading a resource file from either a "regular" file or a jarred file

We're developing a webapp and we have some files to read from a resources directory. During preliminary development and testing, we'd like to be able to read directly from the file in the resources directory. On the other hand, we want to read the resource file from a jar file when the webapp is deployed.
I've read other questions that indicate how to read files from jars. The essence of the idea is to get a BufferedReader and to read from that.
I've written the following code that allows me to create a BufferedReader from either the file system or a jar file, passing in the file name, e.g. myResource.txt, and the ClassLoader, e.g. getClass().getClassLoader(). It seems like it could be made better and/or simpler. Please help.
public static BufferedReader getBufferedReader(String fileToFind,
ClassLoader classLoader) {
BufferedReader bufferedReader = null;
// Try to find file in file system
final URL resource =
classLoader.getResource(fileToFind);
if (resource != null) {
String fileName = resource.getFile();
if (fileName != null) {
try {
final FileReader fileReader = new FileReader(fileName);
bufferedReader = new BufferedReader(fileReader);
}
catch (FileNotFoundException e) {} // no problem, move on
}
}
if (bufferedReader == null) {
// Try to find file in jar file
InputStream inputStream =
classLoader.getResourceAsStream(fileToFind);
final InputStreamReader streamReader = new InputStreamReader(inputStream);
bufferedReader = new BufferedReader(streamReader);
}
return bufferedReader;
}
Rather than trying to address the resource as a File just ask the ClassLoader to return an InputStream for the resource instead via getResourceAsStream:
InputStream in = getClass().getResourceAsStream("/file.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
As long as the file.txt resource is available on the classpath then this approach will work the same way regardless of whether the file.txt resource is in a classes/ directory or inside a jar.
One cannot turn a resource "file" inside a jar into a File. Only when classpath is immediately on classes, such as an unpacked war file. Such a resource has an URL like file:jar:/.../xxx.jar!.../yyy.txt
However, one could use Path & a file system view to copy a Path from a resource.
In your code it suffices to just use getResourceAsStream.
public static BufferedReader getBufferedReader(String fileToFind,
ClassLoader classLoader) {
InputStream inputStream = classLoader.getResourceAsStream(fileToFind);
InputStreamReader streamReader = new InputStreamReader(inputStream,
StandardCharsets.UTF_8);
return new BufferedReader(streamReader);
}
Mind fileToFind should not start with a / and should be an absolute path, when using a ClassLoader.
I specified the Charset, as you are taking the default, which would differ on a Linux production server, and a local Windows developer's machine.

Reading text file works in IDE but not in .jar

I am using
File file = new File("res/movies.txt");
to read text from a bundled .txt file. My code works perfectly when running the program within IntelliJ IDEA, but when I create a .jar file and run it, it gives a "File not found" error. What can I do to make the code work both in the IDE as well as in the jar file?
You need to load the file as a resource. You can use Class.getResourceAsStream or ClassLoader.getResourceAsStream; each will give return an InputStream for the resource.
Once you've got an InputStream, wrap it in an InputStreamReader (specifying the appropriate encoding) to read text from it.
If you need to sometimes read from an arbitrary file and sometimes read from a resource, it's probably best to use separate paths to either create a FileInputStream for the file or one of the methods above for a resource, then do everything else the same way after that.
Here's an example which prints each line from resources/names.txt which should be bundled in the same jar file as the code:
package example;
import java.io.*;
import java.nio.charset.*;
public class Test {
public static void main(String[] args) throws IOException {
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(
Test.class.getResourceAsStream("/resources/names.txt"),
StandardCharsets.UTF_8))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
}
}
}
try to change
File file = new File("res/movies.txt");
to
File file = new File("res/movies.jar");
this of course assumes the filename is movies.jar

Cannot find file in netbeans + glassfish project

Here it is my folder project
I would like to read the file book-form.html which is in the directory web of my project and put it in a String.
This is how I call my function 'getFileContent':
String content = getFileContent("web/book-form.html");
And this is the function:
public String getFileContent(String filePath){
String line, content = new String();
try {
File file = new File(filePath);
FileReader fr = new FileReader(file);
BufferedReader br = new BufferedReader(fr);
while((line = br.readLine()) != null){
content += line;
}
br.close();
fr.close();
} catch(IOException e){
System.out.println(e.getMessage());
}
return content;
}
My problem is that netbeans tell me that it cannot find my file book-form.html
Any ideas ?
File path to resource in our war/WEB-INF folder?
Also you should close stream in a final block or use try-with-resource if you use jdk 7+
I find the way to do it:
Basically the program is in the main folder of Glassfish, so it's needed to put the entire path of your file from the root of your system to allow the program to find your file.

BuferredReader problems

I am having trouble reading from a file. Here is my code can anyone show me where I am wrong?
public static Map<Route, List<Service>> read(String fileName)
throws IOException, FormatException {
BufferedReader reader = new BufferedReader(new FileReader(fileName));
String strLine;
while((strLine = reader.readLine())!= null)
{
/* Own Code */
}
reader.close();
}
I am having a FileNotFound Exception. May this be a the location of my file that is wrong?
You seem to want to use a resource. A resource is not accessed as a file, it is better to use it as a stream.
InputStream resourceStream = MyClass.class.getResourceAsStream(fileName);
BufferedReader myReader = new BufferedReader(new InputStreamReader(resourceStream));
Above code takes the location of your class in account, so you can simply use the fileName as is, without a path, and place the fileName next to your .java file. It will automatically be placed next to the generated .class files and - when packaged - in your .jar file.
Just as owlstead commented keep in appropriate location and try like this
URL url = ClassLoader.getSystemResource(fileName);
br = new BufferedReader(new InputStreamReader(url.openStream()));
i.e keep the file in classes folder or bundle with jar or current working directory etc.

issue with having java in a tomcat servlet edit a .txt file

Hey guys I am trying to have my code, once run through; it will insert into a .txt document that is already made, in the WebContent directory. I am running in Apache Tomcat v7.0 - building in Eclispe.
CODE:
public static void insertWinner(String winner) throws IOException{
String filename= "Winner.txt";
FileWriter fw = new FileWriter(filename,true); //the true will append the new data
fw.write("Winner is" + winner);//appends the string to the file
fw.close();
}
This is being done inside a java file called BandIO which the servlet BandListServ.java calls on to insert a string value into the above code.
Nothing happen when I do this, not to sure why either.
Let me know if you need anyother info, Thanks again!
EDIT
I change it to this -
public static void insertWinner(String winner) throws IOException{
FileWriter out = new FileWriter("Winner.txt");
out.write("Hello");
out.close();
out = new FileWriter("Winner.txt", true);
out.write(", world!");
out.close();
}
EDIT:
Okay so I tried this inside the servlet file but no cigar..
response.setContentType("text/html");
String filename = "Winner.txt";
ServletContext context = getServletContext();
InputStream is = context.getResourceAsStream(filename);
if (is != null) {
InputStreamReader isr = new InputStreamReader(is);
BufferedReader reader = new BufferedReader(isr);
PrintWriter writer = response.getWriter();
String text = "Winner is";
while ((text = reader.readLine()) != null) {
writer.println(text);
}
}
In principle access to the file system is done with
File file = getServletContext().getRealPath("/Winner.txt");
This file could be null, namely when the web application is deployed as .war (so zip format), and the web server is not configured to unpack the war.
In your case a file could have a concurrency problem, needing some locking. Maybe you should use a database table.
Also on next deployment the file might get lost.

Categories

Resources