Question

I'm on Java 6 and I have a method that scans the runtime classpath for a file called config.xml. If found, I would like to read the contents of the file into a string:

InputStream istream = this.getClass().getClassLoader().getResourceAsStream("config.xml");
if(istream != null) {
    System.out.println("Found config.xml!");

    StringBuffer fileData = new StringBuffer(1000);
    BufferedReader reader;
    try {
        reader = new BufferedReader(new FileReader(fileName));
        char[] buf = new char[1024];
        int numRead = 0;
        while((numRead=reader.read(buf)) != -1) {
            String readData = String.valueOf(buf, 0, numRead);
            fileData.append(readData);
            buf = new char[1024];
            reader.close();
        }
    } catch (FileNotFoundException fnfExc) {
        throw new RuntimeException("FileNotFoundException: " + fnfExc.getMessage());
    } catch (IOException ioExc) {
        throw new RuntimeException("IOException: " + ioExc.getMessage());
    }
}

When I run this code, I get the following console output:

Found config.xml!
Exception in thread "main" java.lang.RuntimeException: FileNotFoundException: config.xml (No such file or directory)
    at com.me.myapp.Configurator.readConfigFileFromClasspath(Configurator.java:556)
    at com.me.myapp.Configurator.<init>(Configurator.java:34)
    ...rest of stack trace omitted for brevity

So the classpath scan for config.xml is successful, but then the reader can't seem to find the file. Why??? My only theory is that when config.xml is found on the classpath, it doesn't contain an absolute path to the location of the file on the file system, and perhaps that's what the reader code is looking for.

Was it helpful?

Solution 2

From your given example, it is not clear what fileName refers to. You should just use the stream you got from getResourceAsStream()to read you file, something along

reader = new BufferedReader(new InputStreamReader(istream));

And you should avoid to repeatedly allocating buf new for every read cycle, once is enough.

OTHER TIPS

You use a resource from a classloader.

Instead of doing:

InputStream istream = this.getClass().getClassLoader().getResourceAsStream("config.xml");

do:

URL url = getClass().getResource("config.xml");

That URL will have the path (use .toURI().getPath()). To open the matching input stream afterwards, use .openStream().

You know at least that the resource exists: if it doesn't, .getResource{,AsStream}() both return null (instead of throwing an IOException, which is doubtful imho)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top