открытый ресурс с относительным путем в java
Вопрос
В моем Java-приложении мне нужно получить некоторые файлы и каталоги.
Это структура программы:
./main.java
./package1/guiclass.java
./package1/resources/resourcesloader.java
./package1/resources/repository/modules/ -> this is the dir I need to get
./package1/resources/repository/SSL-Key/cert.jks -> this is the file I need to get
guiclass
загружает класс resourcesloader, который будет загружать мои ресурсы (каталог и файл).
Что касается файла, я попытался
resourcesloader.class.getClass().getResource("repository/SSL-Key/cert.jks").toString()
для того, чтобы получить реальный путь, но этот способ не работает.
Я понятия не имею, как создать каталог.
Решение
Укажите путь относительно classloader, а не класс, из которого вы получаете загрузчик.Например:
resourcesloader.class.getClassLoader().getResource("package1/resources/repository/SSL-Key/cert.jks").toString();
Другие советы
У меня были проблемы с использованием getClass().getResource("filename.txt")
способ.После прочтения инструкций Java docs, если ваш ресурс не находится в том же пакете, что и класс, из которого вы пытаетесь получить доступ к ресурсу, то вы должны указать ему относительный путь, начинающийся с '/'
.Рекомендуемая стратегия заключается в том, чтобы поместить ваши файлы ресурсов в папку "ресурсы" в корневом каталоге.Так, например, если у вас есть структура:
src/main/com/mycompany/myapp
затем вы можете добавить папку ресурсов, как рекомендовано maven в:
src/main/resources
кроме того, вы можете добавить вложенные папки в папку ресурсов
src/main/resources/textfiles
и скажите, что ваш файл называется myfile.txt
итак, у вас есть
src/main/resources/textfiles/myfile.txt
Теперь вот где возникает дурацкая проблема с путем.Допустим, у вас есть класс в вашем com.mycompany.myapp package
, и вы хотите получить доступ к myfile.txt
файл из вашей папки ресурсов.Некоторые говорят, что вам нужно дать:
"/main/resources/textfiles/myfile.txt" path
или
"/resources/textfiles/myfile.txt"
и то, и другое неверно.После того, как я убежал mvn clean compile
, файлы и папки копируются в:
myapp/target/classes
папка.Но папки resources там нет, только папки в папке resources.Итак, у вас есть:
myapp/target/classes/textfiles/myfile.txt
myapp/target/classes/com/mycompany/myapp/*
итак, правильный путь, который нужно указать для getClass().getResource("")
метод заключается в:
"/textfiles/myfile.txt"
вот оно:
getClass().getResource("/textfiles/myfile.txt")
Это больше не будет возвращать значение null, но вернет ваш класс.Я надеюсь, что это кому-нибудь поможет.Для меня странно, что "resources"
папка также не копируется, копируются только вложенные папки и файлы непосредственно в "resources"
папка.Мне казалось бы логичным, что "resources"
папка также будет найдена в разделе "myapp/target/classes"
В надежде предоставить дополнительную информацию для тех, кто не разбирается в этом так быстро, как другие, я хотел бы представить свой сценарий, поскольку он имеет несколько иную настройку.Мой проект был настроен со следующей структурой каталогов (с использованием Eclipse):
Project/ src/ // application source code org/ myproject/ MyClass.java test/ // unit tests res/ // resources images/ // PNG images for icons my-image.png xml/ // XSD files for validating XML files with JAXB my-schema.xsd conf/ // default .conf file for Log4j log4j.conf lib/ // libraries added to build-path via project settings
У меня возникли проблемы с загрузкой моих ресурсов из RES справочник.Я хотел, чтобы все мои ресурсы были отделены от моего исходного кода (просто для целей управления / организации).Итак, что мне нужно было сделать, так это добавить RES каталог к путь построения а затем получите доступ к ресурсу через:
static final ClassLoader loader = MyClass.class.getClassLoader();
// in some function
loader.getResource("images/my-image.png");
loader.getResource("xml/my-schema.xsd");
loader.getResource("conf/log4j.conf");
ПРИМЕЧАНИЕ: В /
пропускается в начале строки ресурса, потому что я использую Загрузчик классов.getResource(строка) вместо того , чтобы Class.getResource(строка).
@GianCarlo:Вы можете попробовать вызвать системное свойство user.dir, которое предоставит вам корень вашего java-проекта, а затем добавить этот путь к вашему относительному пути, например:
String root = System.getProperty("user.dir");
String filepath = "/path/to/yourfile.txt"; // in case of Windows: "\\path \\to\\yourfile.txt
String abspath = root+filepath;
// using above path read your file into byte []
File file = new File(abspath);
FileInputStream fis = new FileInputStream(file);
byte []filebytes = new byte[(int)file.length()];
fis.read(filebytes);
Когда вы используете 'getResource' для класса, относительный путь определяется на основе пакета, в котором находится класс.Когда вы используете 'getResource' в ClassLoader, относительный путь определяется на основе корневой папки.
Если вы используете абсолютный путь, оба метода 'getResource' будут запускаться в корневой папке.
Для тех, кто использует eclipse + maven.Допустим, вы пытаетесь получить доступ к файлу images/pic.jpg
в src/main/resources
.Делая это таким образом :
ClassLoader loader = MyClass.class.getClassLoader();
File file = new File(loader.getResource("images/pic.jpg").getFile());
является совершенно правильным, но может привести к исключению нулевого указателя.Похоже, что eclipse не сразу распознает папки в структуре каталогов maven как исходные папки.Путем удаления и src/main/resources
папку из списка исходных папок проекта и поместив ее обратно (проект> свойства> путь сборки java> исходный код> удалить / добавить папку), я смог решить эту проблему.
resourcesloader.class.getClass()
Может быть разбит на:
Class<resourcesloader> clazz = resourceloader.class;
Class<Class> classClass = clazz.getClass();
Это означает, что вы пытаетесь загрузить ресурс с помощью класса bootstrap.
Вместо этого вы, вероятно, хотите что-то вроде:
resourcesloader.class.getResource("repository/SSL-Key/cert.jks").toString()
Если бы только javac предупреждал о вызове статических методов в нестатических контекстах...
Выполняете ли вы следующую работу?
resourcesloader.class.getClass().getResource("/package1/resources/repository/SSL-Key/cert.jks")
Есть ли причина, по которой вы не можете указать полный путь, включая пакет?
Переходим к двум ответам, как упоминалось выше.Первый из них
resourcesloader.class.getClassLoader().getResource("package1/resources/repository/SSL-Key/cert.jks").toString();
resourcesloader.class.getResource("repository/SSL-Key/cert.jks").toString()
Должно быть одно и то же?
Я внес небольшую модификацию в один лайнер @jonathan.cone ( добавив .getFile()
), чтобы избежать исключения нулевого указателя, и указывая путь к каталогу данных.Вот что сработало у меня :
String realmID = new java.util.Scanner(new java.io.File(RandomDataGenerator.class.getClassLoader().getResource("data/aa-qa-id.csv").getFile().toString())).next();
Используй это:
resourcesloader.class.getClassLoader().getResource("/path/to/file").**getPath();**
Чтобы получить реальный путь к файлу, вы можете попробовать это:
URL fileUrl = Resourceloader.class.getResource("resources/repository/SSL-Key/cert.jks");
String pathToClass = fileUrl.getPath;
Загрузчик ресурсов здесь - это имя класса."ресурсы/репозиторий/SSL-ключ/cert.jks" - это относительный путь к файлу.Если бы у вас был ваш guiclass в ./package1 / java с оставшейся структурой папок, вы бы выбрали "../resources/repository / SSL-Key /cert.jks" в качестве относительного пути из-за правил, определяющих относительный путь.
Таким образом, вы можете прочитать свой файл с помощью BufferedReader.НЕ ИСПОЛЬЗУЙТЕ СТРОКУ для определения пути к файлу, потому что если у вас в пути есть пробелы или какие-то символы не английского алфавита, у вас возникнут проблемы, и файл не будет найден.
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(fileUrl.openStream()));