Reading a text file in war archive [duplicate]

Posted on

Reading a text file in war archive [duplicate]Error is an illegal operation performed by the user which results in the abnormal working of the program. By now, you’ve probably seen a few errors, either when compiling or running your code like Reading a text file in war archive [duplicate]. It can be frustrating, but they can also give you a lot of information about exactly how you can fix the problems in your code about java and jsf. In this post covers the types of errors you’ll see when programming in Java, and how to fix them. Don’t pay any attention to the number of errors. Just read the first error message and work on fixing that error.

Problem :

I am trying to read a text file from my war archive and display the contents in a facelets page at runtime. My folder structure is as follows

+war archive > +resources > +email > +file.txt

I try to read the file in the resources/email/file.txt folder using the following code

File file = new File("/resources/email/file.txt");
BufferedReader reader = null;
try {
    reader = new BufferedReader(new FileReader(file));
} catch (FileNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
StringBuffer buffer = new StringBuffer();
if (reader != null) {
    String line = reader.readLine();
    while (line != null) {
        buffer.append(line);
        line = reader.readLine();
// other lines of code

The problem however is that when I the method with the above code runs, A FileNotFoundException is thrown. I have also tried using the following line of code to get the file, but has not been successful

File file = new File(FacesContext.getCurrentInstance()
        .getExternalContext().getRequestContextPath() + "/resources/email/file.txt");

I still get the FileNotFoundException. How is this caused and how can I solve it?

Solution :

Try below:

   InputStream inputStream = 
      getClass().getClassLoader().getResourceAsStream("/resources/email/file.txt");
   BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream ));

Try to avoid the File, as this is for reading things from the file system.

As your resource is bundled into the WAR, you can access it via the classloader.

Ensure that the resource is bundled into your WEB-INF/classes folder.

InputStream in =
new InputStreamReader(FileLoader.class.getClassLoader().getResourceAsStream("/resources/email/file.txt") );

This is a good blog on the topic

http://haveacafe.wordpress.com/2008/10/19/how-to-read-a-file-from-jar-and-war-files-java-and-webapp-archive/

If you want to get the java File object, you can try this:

String path = Thread.currentThread().getContextClassLoader().getResource("language/file.xml").getPath();
File f = new File(path);
System.out.println(f.getAbsolutePath());

I prefer this approach:

InputStream inputStream = getClass().getResourceAsStream("/resources/email/file.txt");

if (inputStream != null) {
    try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
       ...
    } catch ...
} else ...

Three reasons:

  • it supports both: loading resources from an absolute path and from a relative path (starting from the given class) — see also this answer
  • the way to obtain the stream is one step shorter
  • it utilizes the try-with-resources statement to implicitly close the underlying input stream

Leave a Reply

Your email address will not be published. Required fields are marked *