Search code examples
javafiletextpathrelative-path

Java: Relative path to external text file


I am a bit confused with path in Java (using Eclipse). This is my file structure:

 Folder

    Subfolder

        file.txt

    jarfile.jar

So, I am trying to make the jar file parse data from file.txt and I use the following code:

Scanner in = new Scanner(this.getClass().getResourceAsStream("./Subfolder/file.txt"));

I have made a runnable jar file with Eclipse, put it in the Folder, but it does not work. What is it that I am doing wrong?


Solution

  • Since you use a resource file via a Class object, the path to the resource must be absolute:

    getClass().getResourceAsStream("/Subfolder/file.txt");
    

    Note that doing what you do is a bad idea, that is, opening a scanner on a resource which you don't have a reference to:

    new Scanner(someInputStreamHere());
    

    you have no reference to that input stream, therefore you cannot close it.

    What is more, .getResource*() return null if the resource does not exist; in this case you'll get an NPE!

    Recommended if you use Java 6 (using Guava's Closer):

    final URL url = getClass().getResource("/path/to/resource");
    
    if (url == null) // Oops... Resource does not exist
        barf();
    
    final Closer closer = Closer.create();
    final InputStream in;
    final Scanner scanner;
    
    try {
        in = closer.register(url.openStream());
        scanner = closer.register(new Scanner(in));
        // do stuff
    } catch (IOException e) {
        throw closer.rethrow(e);
    } finally {
        closer.close();
    }
    

    If you use Java 7, just use a try-with-resources statement:

    final URL url = getClass().getResource("/path/to/resource");
    
    if (url == null) // Oops... Resource does not exist
        barf();
    
    final InputStream in;
    final Scanner scanner;
    
    try (
        in = url.openStream();
        scanner = new Scanner(in);
    ) {
        // do stuff
    } catch (IOException e) {
        // deal with the exception if needed; or just declare it at the method level
    }