Как получить абсолютный путь к файлу Java из InputStream?

Я использую Java 6, и у меня есть метод, который сканирует путь к классам среды выполнения для файла с именем config.xml. Если он найден, я хотел бы прочитать содержимое файла в строку:

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());
    }
}

Когда я запускаю этот код, я получаю следующий вывод консоли:

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

Таким образом, сканирование пути к классам для config.xml прошло успешно, но читатель не может найти файл. Почему??? Моя единственная теория заключается в том, что когда config.xml находится в пути к классам, он не содержит абсолютного пути к местоположению файла в файловой системе, и, возможно, это то, что код читателя ищет.


person Community    schedule 26.06.2013    source источник
comment
Вы пробовали this.getClass().getResourceAsStream("config.xml")?   -  person Vishal K    schedule 27.06.2013
comment
Почему бы просто не прочитать прямо из istream?   -  person raptortech97    schedule 27.06.2013


Ответы (2)


Из приведенного вами примера неясно, к чему относится fileName. Вы должны просто использовать поток, который вы получили от getResourceAsStream(), чтобы прочитать файл, что-то вроде

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

И вам следует избегать повторного выделения buf new для каждого цикла чтения, достаточно одного раза.

person Gyro Gearless    schedule 26.06.2013

Вы используете ресурс из загрузчика классов.

Вместо того, чтобы делать:

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

do:

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

Этот URL-адрес будет иметь путь (используйте .toURI().getPath()). Чтобы впоследствии открыть соответствующий входной поток, используйте .openStream().

По крайней мере, вы знаете, что ресурс существует: если его нет, .getResource{,AsStream}() оба возвращают null (вместо того, чтобы выбрасывать IOException, что имхо сомнительно)

person fge    schedule 26.06.2013
comment
ваше решение для URL помогло мне, оно работает, когда вы не можете указать загрузчик контекста. - person Uriel Arvizu; 09.07.2015
comment
почему бы не использовать только .getPath()? - person wyx; 19.12.2019
comment
@wyx Путь по-прежнему закодирован в URL-адресе, пока вы не вызовете toURI(). См. этот ответ - person takanuva15; 13.07.2020
comment
.getResource() не работает при попытке доступа к файлу внутри .jar - person jcflorezr; 25.07.2021