Я хочу прочитать XML-файл, который находится внутри одного из jar файлов, включенных в мой путь к классу. Как я могу прочитать любой файл, который включен в jar?
Переведено автоматически
Ответ 1
Если вы хотите прочитать этот файл из своего приложения, используйте:
Путь начинается с "/", но это путь не в вашей файловой системе, а в вашем classpath . Итак, если ваш файл находится по пути к классу "org.xml" и вызывается myxml.xml ваш путь выглядит как "/org/xml/myxml.xml".
InputStream считывает содержимое вашего файла. Вы можете перенести его в программу чтения, если хотите.
Ответ 2
Ах, это одна из моих любимых тем. По сути, есть два способа загрузить ресурс через classpath:
Class.getResourceAsStream(resource)
и
ClassLoader.getResourceAsStream(resource)
(существуют и другие способы, которые предполагают получение URL-адреса ресурса аналогичным образом, а затем открытие соединения с ним, но это два прямых способа).
Первый метод фактически делегирует второму, после искажения имени ресурса. По сути, существует два вида имен ресурсов: абсолютные (например, "/путь / к /ресурсу /resource") и относительные (например, "ресурс"). Абсолютные пути начинаются с "/".
Вот пример, который должен проиллюстрировать. Рассмотрим класс com.example.A. Рассмотрим два ресурса, один из которых расположен в /com/example/nested, другой в /top , в classpath. Следующая программа показывает девять возможных способов доступа к двум ресурсам:
В основном все происходит так, как вы ожидаете. Ошибка Case-3 связана с тем, что относительное разрешение класса выполняется по отношению к классу, поэтому "top" означает "/ com / example / top", но " / top" означает то, что там написано.
Ошибка Case-5 завершается с ошибкой, потому что относительное разрешение classloader выполняется по отношению к classloader. Но неожиданно ошибка Case-6 также завершается с ошибкой: можно было бы ожидать, что "/ com / example / nested" разрешится должным образом. Для доступа к вложенному ресурсу через classloader вам нужно использовать Case-7, то есть вложенный путь относительно корня classloader. Аналогично, ошибка Case-9 завершается с ошибкой, но ошибка Case-8 проходит.
Помните: для класса java.lang.getResourceAsStream() делегирует classloader:
открытый входной поток getResourceAsStream(имя строки) { name = ResolveName(имя); ClassLoader cl = getClassLoader0(); if (cl==null) { // Системный класс. верните ClassLoader.getSystemResourceAsStream(имя); } верните cl.getResourceAsStream(имя); }
итак, важно поведение ResolveName() .
Наконец, поскольку именно поведение classloader загружает класс, который по существу управляет getResourceAsStream(), а classloader часто является пользовательским загрузчиком, то правила загрузки ресурсов могут быть еще более сложными. например, для веб-приложений загружайте из WEB-INF / classes или WEB-INF / lib в контексте веб-приложения, но не из других изолированных веб-приложений. Кроме того, хорошо управляемые загрузчики классов делегируют родительские права, так что дублирующиеся ресурсы в classpath могут быть недоступны с помощью этого механизма.
// xml file location at xxx.jar // + folder // + folder // xmlFileNameInJarFile.xml
Ответ 4
JAR - это, по сути, ZIP-файл, поэтому относитесь к нему соответственно. Ниже приведен пример того, как извлечь один файл из WAR-файла (также относитесь к нему как к ZIP-файлу) и выводит строковое содержимое. Для двоичного файла вам нужно будет изменить процесс извлечения, но для этого есть множество примеров.
while (e.hasMoreElements()) { ZipEntryentry= (ZipEntry) e.nextElement(); // if the entry is not directory and matches relative file then extract it if (!entry.isDirectory() && entry.getName().equals(relativeFilePath)) { BufferedInputStreambis=newBufferedInputStream( zipFile.getInputStream(entry)); // Read the file // With Apache Commons I/O StringfileContentsStr= IOUtils.toString(bis, "UTF-8");
// With Guava //String fileContentsStr = new String(ByteStreams.toByteArray(bis),Charsets.UTF_8); // close the input stream. bis.close(); return fileContentsStr; } else { continue; } } } catch (IOException e) { logger.error("IOError :" + e); e.printStackTrace(); } returnnull; }
В этом примере я использую Apache Commons I / O, и если вы используете Maven, вот зависимость: