I would like to load an image from my current src directory where the java class files are located as well. However, I always get an IOException..
And how can I make sure the file gets loaded properly on Mac/Linux as well on Windows?
My code so far:
String dir = System.getProperty("user.dir") + "/Logo_transparent.png";
File imageFile = new File(dir);
BufferedImage bufferedImage = null;
try {
bufferedImage = ImageIO.read(imageFile);
} catch (IOException e) {
System.out.println(e.getMessage());
System.out.println(dir);
System.out.println();
}
IOException message:
Can't read input file!
(My path is correct - is it because of the space between Google and Drive?)
/Users/myMac/Google Drive/Privat/Programming/Logo_transparent.png
Kind regards and thank you!
I think It's because you didn't create the file, You can create the file if it doesn't exist by using this code
if(!imageFile.exists()) imageFile.createNewFile();
You're code will look like this
String dir = System.getProperty("user.dir") + "/Logo_transparent.png";
File imageFile = new File(dir);
BufferedImage bufferedImage = null;
try {
if(!imageFile.exists()) imageFile.createNewFile();
bufferedImage = ImageIO.read(imageFile);
} catch (IOException e) {
System.out.println(e.getMessage());
System.out.println(dir);
System.out.println();
}
Also you shouldn't concat child files like that instead pass it as a second argument.
File imageFile = new File(System.getProperty("user.dir"), "Logo_transparent.png");
If your image files will be packaged together with your class files (for example in the same .jar) you should not use File but read it as a resource:
bufferedImage = ImageIO.read(this.getClass().getResourceAsStream("/Logo_transparent.png"));
Notice the '/' before the file name. This means to search in the root path of the classpath.
If you specify without / it will search in the package of this (the current class)
this.getClass().getResourceAsStream("Logo_transparent.png")
You can try to build the absolute path to the image like here and read it afterward.
Related
**I am trying to save and get Player objects from a Textfile and it works when using my IDE but when i create a Jar it can't find the text File. I tried with
this.getClas().getResources(path)
But still it didnt find the path to my text file.Can anybody Help?
public void setPlayer() throws FileNotFoundException {
ArrayList<Player> playerArrayList = new ArrayList<>();
playerArrayList = getPlayers();
Player player = new Player();
player.name = ViewManager.name;
player.score = Collision.points;
playerArrayList.add(player);
try{
FileOutputStream fileOut = new FileOutputStream("src/resources/highscore.txt");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
for(Player player1 : playerArrayList){
out.writeObject(player1);
}
out.close();
fileOut.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
ยดยดยดยด
Resource files are not physical Files, as they can be inside a jar. They are intended to be read-only, and the class loader may cache them. They are case sensitive, with / as path separator and there path starts at the class path's root, probably src/resources.
So use the resource file as fall back resource to copy, if some physical file does not exist.
Path appDir = Paths.get(System.getProperty("user.home") + ".myapp");
Files.createDirectories(appDir);
Path file = appDir.resolve("highscore.txt");
if (!Files.exists(file)) {
// Copy resource to file, either:
URL url = getClass().getResource("/highscore.txt");
Path templatePath = Paths.get(url.toURI());
Files.copy(templatePath, file);
// Or
InputStream templateIn = getClass().getResourceAsStream("/highscore.txt");
Files.copy(templateIn, file);
}
try (FileOutputStream out = Files.newOutputStream(file)) {
...
}
Path is the generalisation of File.
I don't know what IDE you're using, but you're writing the file to the source sub directory. That directory might not be included in the jar.
I'm trying to access a resource from a jar file. The resource is located in the same directory where is the jar.
my-dir:
tester.jar
test.jpg
I tried different things including the following, but every time the input stream is null:
[1]
String path = new File(".").getAbsolutePath();
InputStream inputStream = this.getClass().getResourceAsStream(path.replace("\\.", "\\") + "test.jpg");
[2]
File f = new File(this.getClass().getProtectionDomain().getCodeSource().getLocation().toURI().getPath());
InputStream inputStream = this.getClass().getResourceAsStream(f.getParent() + "test.jpg");
Can you give me some hints? Thanks.
If you are sure, that your application's current folder is the folder of the jar, you can simply call InputStream f = new FileInputStream("test.jpg");
The getResource methods will load stuff using the classloader, not through filesystem. This is why your approach (1) failed.
If the folder containing your *.jar and image file is in the classpath, you can get the image resource as if it was on the default-package:
class.getClass().getResourceAsStream("/test.jpg");
Beware: The image is now loaded in the classloader, and as long as the application runs, the image is not unloaded and served from memory if you load it again.
If the path containing the jar file is not given in the classpath, your approach to get the jarfile path is good.
But then simply access the file directly through the URI, by opening a stream on it:
URL u = this.getClass().getProtectionDomain().getCodeSource().getLocation();
// u2 is the url derived from the codesource location
InputStream s = u2.openStream();
Use this tutorial to help you create a URL to a single file in a jar file.
Here's an example:
String jarPath = "/home/user/myJar.jar";
String urlStr = "jar:file://" + jarPath + "!/test.jpg";
InputStream is = null;
try {
URL url = new URL(urlStr);
is = url.openStream();
Image image = ImageIO.read(is);
}
catch(Exception e) {
e.printStackTrace();
}
finally {
try {
is.close();
} catch(Exception IGNORE) {}
}
I need to open a video file with my code, and it works perfectly fine in Eclipse but when I export into a runnable JAR, i get an error "URI not hierarchical".
I have seen people suggest using getResourceAsStream(), but i need to have a file object as i am using Desktop.getDesktop.open(File). Can anyone help me out?
Here is the code:
try {
URI path1 = getClass().getResource("/videos/tutorialVid1.mp4").toURI();
File f = new File(path1);
Desktop.getDesktop().open(f);
} catch (Exception e) {
e.printStackTrace();
}
if it helps my folder list is like
Src
videos
videoFile.mp4
EDIT:
I plan to run this on windows only, and use launch4j to create an exe.
You can copy the file from the jar to a temporary file and open that.
Here's a method to create a temporary file for a given jar resource:
public static File createTempFile(String path) {
String[] parts = path.split("/");
File f = File.createTempFile(parts[parts.length - 1], ".tmp");
f.deleteOnExit();
try (Inputstream in = getClass().getResourceAsStream(path)) {
Files.copy(in, f.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
return f;
}
And here's an example of how you'd use it:
Desktop.getDesktop().open(createTempFile("/videos/tutorialVid1.mp4"));
I'm trying to access a resource from a jar file. The resource is located in the same directory where is the jar.
my-dir:
tester.jar
test.jpg
I tried different things including the following, but every time the input stream is null:
[1]
String path = new File(".").getAbsolutePath();
InputStream inputStream = this.getClass().getResourceAsStream(path.replace("\\.", "\\") + "test.jpg");
[2]
File f = new File(this.getClass().getProtectionDomain().getCodeSource().getLocation().toURI().getPath());
InputStream inputStream = this.getClass().getResourceAsStream(f.getParent() + "test.jpg");
Can you give me some hints? Thanks.
If you are sure, that your application's current folder is the folder of the jar, you can simply call InputStream f = new FileInputStream("test.jpg");
The getResource methods will load stuff using the classloader, not through filesystem. This is why your approach (1) failed.
If the folder containing your *.jar and image file is in the classpath, you can get the image resource as if it was on the default-package:
class.getClass().getResourceAsStream("/test.jpg");
Beware: The image is now loaded in the classloader, and as long as the application runs, the image is not unloaded and served from memory if you load it again.
If the path containing the jar file is not given in the classpath, your approach to get the jarfile path is good.
But then simply access the file directly through the URI, by opening a stream on it:
URL u = this.getClass().getProtectionDomain().getCodeSource().getLocation();
// u2 is the url derived from the codesource location
InputStream s = u2.openStream();
Use this tutorial to help you create a URL to a single file in a jar file.
Here's an example:
String jarPath = "/home/user/myJar.jar";
String urlStr = "jar:file://" + jarPath + "!/test.jpg";
InputStream is = null;
try {
URL url = new URL(urlStr);
is = url.openStream();
Image image = ImageIO.read(is);
}
catch(Exception e) {
e.printStackTrace();
}
finally {
try {
is.close();
} catch(Exception IGNORE) {}
}
In the code sample below, when I test the code in Eclipse it works just fine. However, when I export the jar file and test it via the command line, it throws an error: IIOException: Can't read input file!
private BufferedImage img = null;
private String imgSource;
if (img == null)
{
try {
URL url = getClass().getResource("Images/questionMark.png");
System.out.println(url.getPath());
/* This prints: file:/C:/Users/Keno/Documents/javaFile.jar!/javaFile/Images/questionMark.png */
File file = new File(url.getPath());
img = ImageIO.read(file);
imgSource = file.getName();
} catch (IOException e) {
e.printStackTrace();
}
}
The file I want to get is located inside the Images folder which is inside the javaFile package. I've noticed one thing that may indicate the problem.
In the print statement I have, I notice an exclamation sign at the end of the javaFile.jar section. Is that correct? Could that indicate an issue with the file or structure?
Also, just in case someone has a better suggestion as to how I should load the file, I'll tell you my intentions. I would like to load the file from a relative location (Images folder) in the jar. I would like to display it (Already done in my actual code) and also store the location to be passed later on to another function (also done).
try this
public void test() {
try(InputStream is = getClass().getResourceAsStream("Images/questionMark.png")) {
ImageIO.read(is);
} catch (IOException e) {
e.printStackTrace();
}
}
You should try to check if your class is in the same directory than Images inside your jar.
|
|- Your class
|- Images
|- questionMark.png
Also, have you tried using directly your url object ?
File file = new File(url);