我使用自定义方法从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
为什么找不到文件?
你跳过了太多的障碍。很简单:
FileUtils.class.getResource("path.png");
// -OR-
try (var in = FileUtils.class.getResourceAsStream("path.png")) {
// in is an inputstream.
}
就是你所需要的。请注意,这意味着path.png
文件的搜索位置与FileUtils所在的位置完全相同(甚至是相同的"subdir"(。因此,如果你在C:ProjectsHugoMyAppmyapp.jar
上有一个文件,如果你要解压缩它,你会在里面找到com/foo/pkg/FileUtils.class
,那么字符串path.png
会在那个罐子里找到,并找到com/foo/pkg/path.png
。换句话说,AnyClass.class.getResource("AnyClass.class")
将让类找到自己的类文件。如果要从jar的"根"开始,请添加斜线,即FileUtils.class.getResource("/path.png")
在同一个jar中查找,并在该jar中查找/path.png
。
getResource
返回一个URL。getResourceAsStream
返回一个流(您需要关闭它;像我一样使用try with resources(。几乎每一个使用资源的API都会使用这两种方法中的一种作为输入。例如,ImageIO就是这样做的;它甚至需要一个URL,这样你就可以使用其中一个:
var image = ImageIO.read(FileUtils.class.getResource("imgName + ".png"));
是的。这是一句俏皮话。这将直接从jar文件中加载图像!
您可以尝试使用一个稍微不同的调用,如下所示:
java.net.URL fileUrl = Thread.currentThread().getContextClassLoader().getResource(file);
String filePath = URLDecoder.decode(fileUrl.getPath(), "UTF-8");
image = ImageIO.read(filePath);