我正在使用自定义方法从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。
为什么找不到文件?
答案 0 :(得分:1)
您跳得太多了。很简单:
FileUtils.class.getResource("path.png");
// -OR-
try (var in = FileUtils.class.getResourceAsStream("path.png")) {
// in is an inputstream.
}
是您所需要的。请注意,这意味着将在与FileUtils居住地完全相同的位置(甚至是相同的“ subdir”)中搜索path.png
文件。因此,如果您在C:\Projects\Hugo\MyApp\myapp.jar
上有一个文件,并且要解压缩该文件,则在其中找到com/foo/pkg/FileUtils.class
,然后在该jar中查找字符串path.png
,然后com/foo/pkg/path.png
。换句话说,AnyClass.class.getResource("AnyClass.class")
将使类找到自己的类文件。如果要从jar的“根”开始,请添加一个斜杠,即FileUtils.class.getResource("/path.png")
出现在同一jar中,并且/path.png
位于该jar中。
getResource
返回一个URL。 getResourceAsStream
返回一个流(您需要关闭该流;像我一样使用try-with-resources)。几乎每个使用资源的API都将这两个中的一个作为输入。例如,ImageIO这样做;它甚至需要一个URL,因此您可以使用以下任何一个:
var image = ImageIO.read(FileUtils.class.getResource("imgName + ".png"));
是的。这是一线。这将直接从jar文件中加载图像!
答案 1 :(得分:-1)
您可以尝试使用稍微不同的呼叫,例如:
java.net.URL fileUrl = Thread.currentThread().getContextClassLoader().getResource(file);
String filePath = URLDecoder.decode(fileUrl.getPath(), "UTF-8");
image = ImageIO.read(filePath);