如何获取.jar 资源路径?
How to get .jar resources path?
我正在使用自定义方法从 resources/
文件夹中获取图片。硬编码路径在生产期间编程时效果很好 (src/main/resources/
)。但是,在交付时,我需要使此路径相对于 .jar 根目录。所以我做了这个。
public static Image getImageFromFile(String file)
{
Image image = null;
try
{
String path = FileUtils.class.getClassLoader().getResource(file).toExternalForm();
System.out.println(path);
File pathToFile = new File(path);
image = ImageIO.read(pathToFile);
}
catch (IOException ex) {ex.printStackTrace();}
return image;
}
file:/C:/Users/Hugo/Desktop/Hugo/Java%20Workspace/ClashBot/bin/main/icons/level-label.png
javax.imageio.IIOException: Can't read input file!
at javax.imageio.ImageIO.read(Unknown Source)
at com.lycoon.clashbot.utils.FileUtils.getImageFromFile(FileUtils.java:55)
打印的路径有效,指向对应的图片。但是,该程序引发 IOException。
为什么找不到文件?
您可以尝试使用稍微不同的调用方式,例如:
java.net.URL fileUrl = Thread.currentThread().getContextClassLoader().getResource(file);
String filePath = URLDecoder.decode(fileUrl.getPath(), "UTF-8");
image = ImageIO.read(filePath);
你跳过了太多的障碍。很简单:
FileUtils.class.getResource("path.png");
// -OR-
try (var in = FileUtils.class.getResourceAsStream("path.png")) {
// in is an inputstream.
}
就是你所需要的。请注意,这意味着 path.png
文件在与 FileUtils 所在的位置完全相同(甚至相同 'subdir')的位置进行搜索。因此,如果你有一个文件 C:\Projects\Hugo\MyApp\myapp.jar
,如果你要解压缩它,你会在里面找到 com/foo/pkg/FileUtils.class
,然后字符串 path.png
会在那个 jar 中查找,并且对于 com/foo/pkg/path.png
。换句话说,AnyClass.class.getResource("AnyClass.class")
会让 class 找到它自己的 class 文件。如果你想从 jar 的 'root' 开始,添加一个斜杠,即 FileUtils.class.getResource("/path.png")
在同一个 jar 中查找,对于 /path.png
在那个 jar 中查找。
getResource
returns一个URL。 getResourceAsStream
returns 一个流(你需要关闭它;像我一样使用 try-with-resources)。几乎每个 resource-using API 都会将这两个中的一个作为输入。例如,ImageIO 就是这样做的;它甚至需要一个 URL 所以你可以使用其中一个:
var image = ImageIO.read(FileUtils.class.getResource("imgName + ".png"));
是的。这是一个one-liner。这将直接从 jar 文件中加载图像!
我正在使用自定义方法从 resources/
文件夹中获取图片。硬编码路径在生产期间编程时效果很好 (src/main/resources/
)。但是,在交付时,我需要使此路径相对于 .jar 根目录。所以我做了这个。
public static Image getImageFromFile(String file)
{
Image image = null;
try
{
String path = FileUtils.class.getClassLoader().getResource(file).toExternalForm();
System.out.println(path);
File pathToFile = new File(path);
image = ImageIO.read(pathToFile);
}
catch (IOException ex) {ex.printStackTrace();}
return image;
}
file:/C:/Users/Hugo/Desktop/Hugo/Java%20Workspace/ClashBot/bin/main/icons/level-label.png
javax.imageio.IIOException: Can't read input file!
at javax.imageio.ImageIO.read(Unknown Source)
at com.lycoon.clashbot.utils.FileUtils.getImageFromFile(FileUtils.java:55)
打印的路径有效,指向对应的图片。但是,该程序引发 IOException。
为什么找不到文件?
您可以尝试使用稍微不同的调用方式,例如:
java.net.URL fileUrl = Thread.currentThread().getContextClassLoader().getResource(file);
String filePath = URLDecoder.decode(fileUrl.getPath(), "UTF-8");
image = ImageIO.read(filePath);
你跳过了太多的障碍。很简单:
FileUtils.class.getResource("path.png");
// -OR-
try (var in = FileUtils.class.getResourceAsStream("path.png")) {
// in is an inputstream.
}
就是你所需要的。请注意,这意味着 path.png
文件在与 FileUtils 所在的位置完全相同(甚至相同 'subdir')的位置进行搜索。因此,如果你有一个文件 C:\Projects\Hugo\MyApp\myapp.jar
,如果你要解压缩它,你会在里面找到 com/foo/pkg/FileUtils.class
,然后字符串 path.png
会在那个 jar 中查找,并且对于 com/foo/pkg/path.png
。换句话说,AnyClass.class.getResource("AnyClass.class")
会让 class 找到它自己的 class 文件。如果你想从 jar 的 'root' 开始,添加一个斜杠,即 FileUtils.class.getResource("/path.png")
在同一个 jar 中查找,对于 /path.png
在那个 jar 中查找。
getResource
returns一个URL。 getResourceAsStream
returns 一个流(你需要关闭它;像我一样使用 try-with-resources)。几乎每个 resource-using API 都会将这两个中的一个作为输入。例如,ImageIO 就是这样做的;它甚至需要一个 URL 所以你可以使用其中一个:
var image = ImageIO.read(FileUtils.class.getResource("imgName + ".png"));
是的。这是一个one-liner。这将直接从 jar 文件中加载图像!