Home > Enterprise >  Reading File from another Package in Java using getResourceAsStream()
Reading File from another Package in Java using getResourceAsStream()

Time:05-08

I am trying to read a file called "numbers.txt" which is filled with int numbers (one int per line, no empty lines). I want to put the numbers into an array and return this array (method readIntsFromFile). Unfoutnetly the File does not get found, so the InputStream cls returns null. If I put the file "numbers.txt" into the same folder as the Class ReadFileInput it works but I do not know why it does not work if I put the "numbers.txt" file into the resources folder. I thought getResourceAsStream() can get it there? The main just creates a new class Object and calls the class function with the parameter "numbers.txt" and saves the result in an array.

Here is the Class with the method readIntsFromFile:

package impl;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;

public class ReadFileInput {

    public int[] readIntsFromFile(String path) {
        ArrayList<Integer> arrList = new ArrayList<>();

        try {
            InputStream cls = ReadFileInput.class.getResourceAsStream(path);
            System.out.println("Get Resources as Stream: "   cls);
         
            //Put cls in ArrayList
        
            }
            cls.close();
        } catch (Exception e) {
            System.out.println(e);
        }

        int[] arr = arrList.stream().mapToInt(Integer::intValue).toArray();
        System.out.println(arr);
        return arr;
    }
}

Do you know how it could work?

All the best!

CodePudding user response:

The string value you pass to SomeClass.class.getResource() (as well as getResourceAsStream, of course) has two 'modes'.

  1. It looks 'relative to the package of SomeClass', which means, effectively, if you ask for e.g. "img/load.png", and SomeClass is in the package com.foo, you're really asking for "/com/foo/img/load.png" - this is relative mode.

  2. You want to go into absolute mode: You want the 'classpath source' that provided the SomeClass.class file that the JVM used to load the code for SomeClass, and then look in that same place for, say, /img/load.png from there. In other words, if SomeClass's code was obtained by loading the bytecode from jar file entry /com/foo/SomeClass.class in jarfile myapp.jar, you want the data obtained by loading the jar file entry /img/load.png from jarfile myapp.jar. You can do that - simply start with a slash.

Given that your numbers.txt file appears to be in the 'root' of resources, that would strongly suggest the string you pass to .getResourceAsStream() should be "/numbers.txt". Note the leading slash.

NB: It's not quite a path. .. and such do not work. Weirdly, com.foo.numbers.txt would, if the jar file contains /com/foo/numbers.txt.

  • Related