Java get resources directory path

Как получить путь к ресурсу в файле JAR Java

Я пытаюсь получить путь к ресурсу, но мне не повезло. Это работает (как в IDE, так и в JAR), но таким образом я не могу получить путь к файлу, только содержимое файла:

ClassLoader classLoader = getClass().getClassLoader(); PrintInputStream(classLoader.getResourceAsStream("config/netclient.p")); 
ClassLoader classLoader = getClass().getClassLoader(); File file = new File(classLoader.getResource("config/netclient.p").getFile()); 

Результат: java.io.FileNotFoundException: file:/path/to/jarfile/bot.jar!/config/netclient.p (No such file or directory) Есть ли способ получить путь к файлу ресурсов?

Да. У меня есть класс, с которым я хотел бы работать, как папка снаружи (на случай, если я захочу изменить какой-либо параметр файла конфигурации), так и JAR, который скрывает файлы конфигурации реализации для пользователя (например, распространяемый) Банку всем людям).

Тогда вы, вероятно, должны иметь дело с этим потоком ввода, который вы можете получить из любого источника.

Ну, у меня почти такая же проблема. Я хочу иметь возможность связать и изображение в JAR, а затем во время выполнения использовать это изображение в JTextPanel с использованием HTML. HTML требует либо относительный путь (и установить базу документа на что-то подходящее), либо абсолютный путь. Можете ли вы получить этот путь для файла в JAR?

16 ответов

Это преднамеренно. Содержимое «файла» может быть недоступно в виде файла. Помните, что вы имеете дело с классами и ресурсами, которые могут быть частью файла JAR или другого ресурса. Погрузчик классов не должен предоставлять дескриптор файла для ресурса, например, файл jar, возможно, не был расширен в отдельные файлы в файловой системе.

Читайте также:  Все цвета языка html

Все, что вы можете сделать, получив java.io.File, можно сделать, скопировав поток во временный файл и сделав то же самое, если java.io.File абсолютно необходим.

Вы можете добавить «rsrc:» при вызове ресурса, чтобы открыть его. как новый файл («rsrc: filename.txt»), он будет загружать filename.txt, который упакован в корень вашего фляги

При загрузке ресурса убедитесь, что вы заметили разницу между:

getClass().getClassLoader().getResource("com/myorg/foo.jpg") //relative path 
getClass().getResource("/com/myorg/foo.jpg")); //note the slash at the beginning 

Я предполагаю, что эта путаница вызывает большинство проблем при загрузке ресурса.

Кроме того, когда вы загружаете изображение, проще использовать getResourceAsStream() :

BufferedImage image = ImageIO.read(getClass().getResourceAsStream("/com/myorg/foo.jpg")); 

Когда вам действительно нужно загрузить (не образный) файл из архива JAR, вы можете попробовать это:

 File file = null; String resource = "/com/myorg/foo.xml"; URL res = getClass().getResource(resource); if (res.toString().startsWith("jar:")) < try < InputStream input = getClass().getResourceAsStream(resource); file = File.createTempFile("tempfile", ".tmp"); OutputStream out = new FileOutputStream(file); int read; byte[] bytes = new byte[1024]; while ((read = input.read(bytes)) != -1) < out.write(bytes, 0, read); >file.deleteOnExit(); > catch (IOException ex) < Exceptions.printStackTrace(ex); >> else < //this will probably work in your IDE, but not from a JAR file = new File(res.getFile()); >if (file != null && !file.exists())

+1 Это сработало для меня. Прежде чем использовать путь `/com/myorg/filename.ext ‘, убедитесь, что файлы, которые вы хотите прочитать, находятся в папке bin и перейдите в каталог загрузки классов в ресурсах.

+1 Это также работает для меня . Я понимаю, что могут быть некоторые риски безопасности, связанные с этим подходом, поэтому владельцы приложений должны знать об этом.

Не могли бы вы уточнить это утверждение: «Всегда лучше загружать ресурс с помощью getResourceAsStream ()»? Как это может обеспечить решение проблемы?

@LucaS. Это было предназначено только для случая изображений, извините, это не было очень ясно. Подход должен быть независимым от платформы, хотя это немного хакерский способ.

Я читаю файл WAV из моего файла JAR и записал его, как в вашем примере, в мой каталог TMP. но файлы разные. что случилось и что я могу сделать, чтобы предотвратить это?

Если вы хотите получить файл, например, в корне фляги, необходимо указать абсолютный путь. Также подойдет любой класс; пример: URL url = Object.class.getResource («/» + имя файла);

String path = this.getClass().getClassLoader().getResource().toExternalForm() 

В основном метод getResource выдает URL. Из этого URL вы можете извлечь путь, вызвав toExternalForm()

При запуске из моей среды (IntelliJ) это создает простой URL-адрес файла, который работает во всех случаях. Однако при запуске из самого jar я получаю URI, аналогичный jar: file: /path/to/jar/jarname.jar! /File_in_jar.mp4. Не все могут использовать URI, который начинается с jar. Показательный пример JavaFX Media.

Мне больше нравится этот ответ. Конечно, в большинстве случаев может быть предпочтительнее просто захватить InputStream к ресурсу, когда он находится в файле jar, но если по какой-то причине вам действительно нужен путь, это то, что работает. Мне нужен был путь к стороннему объекту. Тогда спасибо!

вышеприведенное решение не работает в IDE, в Intellijit добавляет file:/ к пути, который работает в jar, но не в IDE

Я провел некоторое время с этой проблемой, потому что никакое решение, которое я нашел, действительно работало, как ни странно! Рабочий каталог часто не является каталогом JAR, особенно если JAR (или любая программа, если на то пошло) запускается из меню «Пуск» под Windows. Итак, вот что я сделал, и он работает для .class файлов, запускаемых извне JAR так же хорошо, как и для JAR. (Я тестировал его только под Windows 7.)

try < //Attempt to get the path of the actual JAR file, because the working directory is frequently not where the file is. //Example: file:/D:/all/Java/TitanWaterworks/TitanWaterworks-en.jar!/TitanWaterworks.class //Another example: /D:/all/Java/TitanWaterworks/TitanWaterworks.class PROGRAM_DIRECTORY = getClass().getClassLoader().getResource("TitanWaterworks.class").getPath(); // Gets the path of the class or jar. //Find the last ! and cut it off at that location. If this isn't being run from a jar, there is no !, so it'll cause an exception, which is fine. try < PROGRAM_DIRECTORY = PROGRAM_DIRECTORY.substring(0, PROGRAM_DIRECTORY.lastIndexOf('!')); >catch (Exception e) < >//Find the last / and cut it off at that location. PROGRAM_DIRECTORY = PROGRAM_DIRECTORY.substring(0, PROGRAM_DIRECTORY.lastIndexOf('/') + 1); //If it starts with /, cut it off. if (PROGRAM_DIRECTORY.startsWith("/")) PROGRAM_DIRECTORY = PROGRAM_DIRECTORY.substring(1, PROGRAM_DIRECTORY.length()); //If it starts with file:/, cut that off, too. if (PROGRAM_DIRECTORY.startsWith("file:/")) PROGRAM_DIRECTORY = PROGRAM_DIRECTORY.substring(6, PROGRAM_DIRECTORY.length()); > catch (Exception e) < PROGRAM_DIRECTORY = ""; //Current working directory instead. >

если netclient.p находится внутри JAR файла, у него не будет пути, потому что этот файл находится внутри другого файла. в этом случае лучший путь, который вы можете получить, действительно file:/path/to/jarfile/bot.jar!/config/netclient.p .

Когда я пытаюсь преобразовать URL-адрес этого формата (. bot.jar! / Config / . ) в URI, он говорит, что путь не является иерархическим.

Вам нужно понять путь в файле jar.
Просто обратитесь к этому родственнику. Поэтому, если у вас есть файл (myfile.txt), расположенный в foo.jar в каталоге \src\main\resources (стиль maven). Вы бы назвали его следующим:

src/main/resources/myfile.txt 

Если вы выгрузите банку с помощью jar -tvf myjar.jar , вы увидите вывод и относительный путь в файле jar и используйте FORWARD SLASHES.

Вы действительно должны использовать косую черту даже в Windows. Это означает, что вы не можете использовать File.separator .

В моем случае я использовал объект URL вместо Path.

File file = new File("my_path"); URL url = file.toURI().toURL(); 

Ресурс в пути к классам с помощью classloader

URL url = MyClass.class.getClassLoader().getResource("resource_name") 

Когда мне нужно прочитать содержимое, я могу использовать следующий код:

InputStream stream = url.openStream(); 

И вы можете получить доступ к контенту с помощью InputStream.

Источник

How to get a path to a resource in a java jar file?

When working with Java applications, it is common to package the application as a JAR (Java Archive) file. This allows for easy distribution and deployment of the application. However, when resources such as images or configuration files are included in the JAR, it can be difficult to access these resources at runtime. This is because the resources are stored in the JAR’s internal file system and are not directly accessible through the file system of the host system. In this guide, we will discuss various methods for getting the path to a resource in a Java JAR file.

Method 1: Using the ClassLoader

To get the path to a resource in a Java JAR file using the ClassLoader, you can follow these steps:

ClassLoader classLoader = getClass().getClassLoader();
URL resourceUrl = classLoader.getResource("path/to/resource.txt");
String resourcePath = resourceUrl.getFile();

Here is an example code that demonstrates these steps:

public class ResourceLoader  public static void main(String[] args)  ClassLoader classLoader = ResourceLoader.class.getClassLoader(); URL resourceUrl = classLoader.getResource("example.txt"); String resourcePath = resourceUrl.getFile(); System.out.println("Resource path: " + resourcePath); > >

In this example, the example.txt file is located in the root directory of the JAR file. The getResource() method returns a URL to this file, and the getFile() method returns the file path as a string.

Note that the getResource() method uses a relative path to the resource, which is resolved relative to the package of the class that calls it. If the resource is located in a different package or directory, you need to adjust the path accordingly.

Also, keep in mind that the getResource() method returns null if the resource is not found. Therefore, you should always check the result for null before using it.

Method 2: Using the Class.getResource() method

To get a path to a resource in a Java JAR file using the Class.getResource() method, you can follow these steps:

  1. Get a reference to the class that will be used to load the resource. This can be done using the getClass() method.
  1. Use the getResource() method to get a URL object that points to the resource. The path to the resource should be relative to the package that contains the class.
URL resourceUrl = clazz.getResource("/path/to/resource");
String resourcePath = resourceUrl.getFile();
File resourceFile = new File(resourcePath);

Here’s an example that demonstrates how to use the Class.getResource() method to load a text file from a JAR file:

class MyClass  public void loadResource() throws IOException  Class?> clazz = getClass(); URL resourceUrl = clazz.getResource("/path/to/resource.txt"); String resourcePath = resourceUrl.getFile(); File resourceFile = new File(resourcePath); String content = new String(Files.readAllBytes(resourceFile.toPath())); System.out.println(content); > >

In this example, the loadResource() method loads a text file located at /path/to/resource.txt in the JAR file that contains the MyClass class. The contents of the file are then printed to the console.

Method 3: Using the Class.getResourceAsStream() method

To get the path to a resource in a Java JAR file using the Class.getResourceAsStream() method, you can follow these steps:

  1. First, get the Class object for the class that will access the resource. You can do this by calling the getClass() method on an instance of the class, or by using the .class syntax on the class name.
Class?> clazz = MyClass.class;
  1. Next, use the getResourceAsStream() method on the Class object to get an InputStream to the resource. This method takes a String argument that represents the path to the resource, relative to the package of the class.
InputStream inputStream = clazz.getResourceAsStream("/path/to/resource.txt");
  1. You can then use the InputStream to read the contents of the resource. For example, you could use a BufferedReader to read the text of a file.
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); String line; while ((line = reader.readLine()) != null)  System.out.println(line); >

Here’s an example that puts it all together:

public class MyClass  public static void main(String[] args) throws IOException  Class?> clazz = MyClass.class; InputStream inputStream = clazz.getResourceAsStream("/path/to/resource.txt"); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); String line; while ((line = reader.readLine()) != null)  System.out.println(line); > > >

This code will read the contents of the resource.txt file located in the /path/to/ directory of the JAR file that contains the MyClass class. Note that the path is specified with a leading / , which indicates that it is an absolute path relative to the root of the JAR file.

Method 4: Using the File class and the URLDecoder class

To get a path to a resource in a Java JAR file using the File class and the URLDecoder class, follow these steps:

URL url = getClass().getResource("/path/to/resource");
String filePath = URLDecoder.decode(url.getFile(), "UTF-8");
File file = new File(filePath);

Here’s the complete code example:

import java.io.File; import java.net.URL; import java.net.URLDecoder; public class JarResourceExample  public static void main(String[] args) throws Exception  // Get the URL of the resource URL url = JarResourceExample.class.getResource("/path/to/resource"); // Convert the URL to a file path String filePath = URLDecoder.decode(url.getFile(), "UTF-8"); // Create a File object using the file path File file = new File(filePath); // Print the absolute path of the file System.out.println(file.getAbsolutePath()); > >

In this example, replace «/path/to/resource» with the actual path to the resource you want to access in the JAR file.

Note that this method may not work if the JAR file is inside a directory with spaces in the path. In that case, you may need to use the JarFile class instead.

Источник

Оцените статью