Есть ли API для получения ресурса classpath (например, из чего я получу Class.getResource(String)
) как java.nio.file.Path
? В идеале я хотел бы использовать новые Path
API с ресурсами classpath.
143
Есть ли API для получения ресурса classpath (например, из чего я получу Class.getResource(String)
) как java.nio.file.Path
? В идеале я хотел бы использовать новые Path
API с ресурсами classpath.
Paths.get(URI)
, затем ´URL.toURI (), and last
getResource () `, который возвращает aURL
. Возможно, вы сможете связать их вместе. Хотя не пробовал.Ответы:
Этот работает для меня:
источник
Thread.currentThread().getContextClassLoader().getResource(resourceName).toURI()
Предположение, что вы хотите сделать, это вызвать Files.lines (...) на ресурсе, который приходит из classpath - возможно, внутри jar.
Так как Oracle запутал понятие, когда Path - это Path, не заставляя getResource возвращать пригодный путь, если он находится в jar-файле, вам нужно сделать что-то вроде этого:
источник
class.getResource
требуется косая черта, ноgetSystemResourceAsStream
не удается найти файл, если в качестве префикса используется косая черта.Наиболее общее решение заключается в следующем:
Основное препятствие состоит в том, чтобы иметь дело с двумя возможностями: либо иметь существующую файловую систему, которую мы должны использовать, но не закрывать (как с
file
URI или хранилищем модуля Java 9), либо иметь необходимость открывать и таким образом безопасно закрывать файловую систему (например, zip / jar файлы).Таким образом, решение, приведенное выше, инкапсулирует фактическое действие в
interface
, обрабатывает оба случая, безопасно закрывая его во втором случае, и работает с Java 7 на Java 10. Перед тем, как открыть новую, она проверяет, существует ли уже открытая файловая система, поэтому также работает в том случае, если другой компонент вашего приложения уже открыл файловую систему для того же файла zip / jar.Он может использоваться во всех версиях Java, указанных выше, например, для перечисления содержимого пакета (
java.lang
в примере) какPath
s, например:В Java 8 или новее вы можете использовать лямбда-выражения или ссылки на методы для представления фактического действия, например
сделать то же самое.
Финальная версия модульной системы Java 9 нарушила приведенный выше пример кода. JRE непоследовательно возвращает путь,
/java.base/java/lang/Object.class
вObject.class.getResource("Object.class")
то время как это должно быть/modules/java.base/java/lang/Object.class
. Это можно исправить, добавив пропущенный,/modules/
если родительский путь указан как несуществующий:Затем он снова будет работать со всеми версиями и методами хранения.
источник
Оказывается, вы можете сделать это с помощью встроенного поставщика Zip File System . Однако передача ресурса URI напрямую в
Paths.get
не будет работать; вместо этого сначала необходимо создать файловую систему zip для URI jar без имени записи, а затем обратиться к записи в этой файловой системе:Обновить:
Было правильно отмечено, что приведенный выше код содержит утечку ресурсов, поскольку код открывает новый объект FileSystem, но никогда не закрывает его. Наилучший подход - передать объект, похожий на Consumer, так же, как это делает ответ Хольгера. Откройте файловую систему ZipFS достаточно долго, чтобы работник мог делать все, что ему нужно, с Path (если работник не пытается сохранить объект Path для последующего использования), затем закройте FileSystem.
источник
newFileSystem
незакрытое может привести к тому, что несколько ресурсов навсегда останутся открытыми. Хотя @raisercostin addendum избегает ошибки при попытке создать уже созданную файловую систему, если вы попытаетесь использовать возвращаемую,Path
вы получите aClosedFileSystemException
. Ответ @Holger хорошо работает для меня.FileSystem
. Если вы загружаете ресурс из Jar-файла и затем создаете необходимыйFileSystem
-FileSystem
он также позволит вам загружать другие ресурсы из того же Jar-файла. Кроме того, после того, как вы создали новый,FileSystem
вы можете просто попытаться загрузить ресурс снова, используя,Paths.get(Path)
и реализация автоматически использует новыйFileSystem
.#getPath(String)
метод наFileSystem
объекте.Я написал небольшой вспомогательный метод для чтения
Paths
из ресурсов вашего класса. Его очень удобно использовать, так как для этого нужна только ссылка на класс, в котором вы сохранили свои ресурсы, а также имя самого ресурса.источник
Вы не можете создать URI из ресурсов внутри файла JAR. Вы можете просто записать его во временный файл и затем использовать его (java8):
источник
Чтение файла из папки ресурсов с помощью NIO, в java8
источник
Вам необходимо определить файловую систему для чтения ресурса из файла jar, как указано в https://docs.oracle.com/javase/8/docs/technotes/guides/io/fsp/zipfilesystemprovider.html . Я успешно прочитал ресурс из jar-файла с кодами ниже:
источник