Hvordan får man .jar ressourcesti?
Jeg bruger en brugerdefineret metode til at hente billeder fra resources/
folder. Den hårdkodede sti fungerer godt ved programmering under produktion (src/main/resources/
). Men når jeg leverer, skal jeg lave denne sti i forhold til .jar-roden. Så jeg lavede denne.
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)
Den udskrevne sti er gyldig og peger på det tilsvarende billede. Programmet rejser dog en IOException.
Hvorfor kan den ikke finde filen?
Svar
Du springer gennem alt for mange bøjler. Det er ganske enkelt:
FileUtils.class.getResource("path.png"); // -OR- try (var in = FileUtils.class.getResourceAsStream("path.png")) { // in is an inputstream. }
er alt hvad du behøver. Bemærk, at dette betyder path.png
fil søges efter på nøjagtig samme sted (og endda samme 'subdir') som hvor FileUtils bor. Så hvis du f.eks. har en fil på C:ProjectsHugoMyAppmyapp.jar
, og hvis du skulle udpakke det, ville du finde com/foo/pkg/FileUtils.class
indeni , derefter strengen path.png
ville kigge i den krukke og efter com/foo/pkg/path.png
. Med andre ord, AnyClass.class.getResource("AnyClass.class")
vil lade en klasse finde sin egen klassefil. Hvis du vil gå fra 'roden' af krukken, skal du tilføje en skråstreg, dvs. FileUtils.class.getResource("/path.png")
ser i samme krukke, og for /path.png
inde i den krukke.
getResource
returnerer en URL. getResourceAsStream
returnerer en stream (som du skal lukke; brug prøv-med-ressourcer som jeg gjorde). Næsten alle ressourcebrugende API derude vil tage en af disse to som input. For eksempel gør ImageIO det; det tager endda en URL, så du kan bruge en af dem:
var image = ImageIO.read(FileUtils.class.getResource("imgName + ".png"));
Ja. Det er en one-liner. Dette vil indlæse billeder direkte fra en jar-fil!