I am reading a file as follows:
File imgLoc = new File("Player.gif");
BufferedImage image = null;
try {
image = ImageIO.read(imgLoc);
}
catch(Exception ex)
{
System.out.println("Image read error");
System.exit(1);
}
return image;
I do not know where to place my file to make the Eclipse IDE, and my project can detect it when I run my code.
Is there a better way of creating a BufferedImage from an image file stored in your project directory?
Take a look in the comments for Class.getResource and Class.getResourceAsStream. These are probably what you really want to use as they will work whether you are running from within the directory of an Eclipse project, or from a JAR file after you package everything up.
You use them along the lines of:
InputStream in = MyClass.class.getResourceAsStream("Player.gif");
In this case, Java would look for the file "Player.gif" next to the MyClass.class file. That is, if the full package/class name is "com.package.MyClass", then Java will look for a file in "[project]/bin/com/package/Player.gif". The comments for getResourceAsStream indicate that if you lead with a slash, i.e. "/Player.gif", then it'll look in the root (i.e. the "bin" directory).
Note that you can drop the file in the "src" directory and Eclipse will automatically copy it to the "bin" directory at build time.
In the run dialog you can choose the directory. The default is the project root.
From my experience it seems to be the containing projects directory by default, but there is a simple way to find out:
System.out.println(new File(".").getAbsolutePath());
Are you trying to write a plugin for Eclipse or is it a regular project?
In the latter case, wouldn't that depend on where the program is installed and executed in the end?
While trying it out and running it from Eclipse, I'd guess that it would find the file in the project workspace. You should be able to find that out by opening the properties dialog for the project, and looking under the Resource entry.
Also, you can add resources to a project by using the Import menu option.
The default root folder for any Eclipse project is also a relative path of that application.
Below are steps I used for my Eclipse 4.8.0 and Java 1.8 project.
I - Place your file you want to interact with along the BIN and SRS folders of your project and not in one of those folders.
II - Implement below code in your main() method.
public static void main(String [] args) throws IOException {
FileReader myFileReader;
BufferedReader myReaderHelper;
try {
String localDir = System.getProperty("user.dir");
myFileReader = new FileReader(localDir + "\\yourFile.fileExtension");
myReaderHelper = new BufferedReader(myFileReader);
if (myReaderHelper.readLine() != null) {
StringTokenizer myTokens =
new StringTokenizer((String)myReaderHelper.readLine(), "," );
System.out.println(myTokens.nextToken().toString()); // - reading first item
}
} catch (FileNotFoundException myFileException) {
myFileException.printStackTrace(); } } // End of main()
III - Implement a loop to iterate through elements of your file if your logic requires this.
Related
I have a javafx project, which contains multiple paths for images and text files :
private Image imgMan = new Image(getClass().getResource("../man.gif").toExternalForm());
FileHelper.resetScores("./bin/application/MAP/BestScores.txt");
...
When i launch from eclipse, it work normally, and access to images and files without any problem.
But when i try to export my project to a jar file, it export correctly, but it don't launch !
I try to launch it from cmd, the trace of stack said that he don't know the paths...
Caused by: java.lang.NullPointerException
at application.Client.(Client.java:31)
(line 31 in my code refer to the first line of code given in the question)
I try to create a resource folder and put all files into it, but no result.
So what is the best way to make it ?
where must i create the resource folder ?
and how to access the files into it from the code ?
Thank you
There are several thing you should check:
verify the path in your jar against the class you are looking. Your image must be there.
verify you have successfully loaded a resource because using it, eg: check if getResource returns null.
For the first point, it depends on how you build your jar:
Eclipse will by default copy class file and resources to bin unless you use m2e. If you use the Extract runnable JAR (from File > Export menu), it may ignore some resources.
If you use Maven then your images must be in src/main/resources by default.
For the second point, you should use a method that should check the resource exists before delegating to Image. While it won't change your core problem, you would have a less subtile error:
static javafx.scene.image.Image loadImage(Class<?> source, String path) {
final InputStream is = source.getResourceAsStream(path);
if (null == is) {
throw new IllegalStateException("Could not load image from " + source + " path: " + path);
}
try (is) { // Java 9 -> you may want to use InputStream is2 = is
return new javafx.scene.image.Image(is); // use is2 for Java < 9
}
}
You should also try with an absolute path (from the root of the jar, or your src/main/resources if you use maven):
Image image = loadImage(this.getClass(), "/images/man.gif");
In Python the global variable __file__ is the full path of the current file.
System.getProperty("user.dir"); seems to return the path of the current working directory.
I want to get the path of the current .java, .class or package file.
Then use this to get the path to an image.
My project file structure in Netbeans looks like this:
(source: toile-libre.org)
Update to use code suggested from my chosen best answer:
// read image data from picture in package
try {
InputStream instream = TesseractTest.class
.getResourceAsStream("eurotext.tif");
bufferedImage = ImageIO.read(instream);
}
catch (IOException e) {
System.out.println(e.getMessage());
}
This code is used in the usage example from tess4j.
My full code of the usage example is here.
If you want to load an image file stored right next to your class file, use Class::getResourceAsStream(String name).
In your case, that would be:
try (InputStream instream = TesseractTest.class.getResourceAsStream("eurotext.tif")) {
// read stream here
}
This assumes that your build system copies the .tif file to your build folder, which is commonly done by IDEs, but requires extra setup in build tools like Ant and Gradle.
If you package your program to a .jar file, the code will still work, again assuming your build system package the .tif file next to the .class file.
Is there a way to get the file path of the .java file executed or compiled?
For completeness, the literal answer to your question is "not easily and not always".
There is a round-about way to find the source filename for a class on the callstack via StackFrameElement.getFileName(). However, the filename won't always be available1 and it won't necessarily be correct2.
Indeed, it is quite likely that the source tree won't be present on the system where you are executing the code. So if you needed an image file that was stashed in the source tree, you would be out of luck.
1 - It depends on the Java compiler and compilation options that you use. And potentially on other things.
2 - For example, the source tree can be moved or removed after compilation.
Andreas has described the correct way to solve your problem. Make sure that the image file is in your application's JAR file, and access it using getResource or getResourceAsStream. If your application is using an API that requires a filename / pathname in the file system, you may need to extract the resource from the JAR to a temporary file, or something like that.
public class Main {
public static void main(String[] args) throws Exception {
System.out.println(getPackageParent(Main.class, false));
}
public static String getPackageParent(Class<?> cls, boolean include_last_dot)
throws Exception {
StringBuilder sb = new StringBuilder(cls.getPackage().getName());
if (sb.lastIndexOf(".") > 0)
if (include_last_dot)
return sb.delete(sb.lastIndexOf(".") + 1, sb.length())
.toString();
else
return sb.delete(sb.lastIndexOf("."), sb.length()).toString();
return sb.toString();
}
}
I have been working on a project that requires the user to "install" the program upon running it the first time. This installation needs to copy all the resources from my "res" folder to a dedicated directory on the user's hard drive. I have the following chunk of code that was working perfectly fine, but when I export the runnable jar from eclipse, I received a stack trace which indicated that the InputStream was null. The install loop passes the path of each file in the array list to the export function, which is where the issue is (with the InputStream). The paths are being passed correctly in both Eclipse and the runnable jar, so I doubt that is the issue. I have done my research and found other questions like this, but none of the suggested fixes (using a classloader, etc) have worked. I don't understand why the method I have now works in Eclipse but not in the jar?
(There also exists an ArrayList of File called installFiles)
private static String installFilesLocationOnDisk=System.getProperty("user.home")+"/Documents/[project name]/Resources/";
public static boolean tryInstall(){
for(File file:installFiles){
//for each file, make the required directories for its extraction location
new File(file.getParent()).mkdirs();
try {
//export the file from the jar to the system
exportResource("/"+file.getPath().substring(installFilesLocationOnDisk.length()));
} catch (Exception e) {
return false;
}
}
return true;
}
private static void exportResource(String resourceName) throws Exception {
InputStream resourcesInputStream = null;
OutputStream resourcesOutputStream = null;
//the output location for exported files
String outputLocation = new File(installFilesLocationOnDisk).getPath().replace('\\', '/');
try {
//This is where the issue arises when the jar is exported and ran.
resourcesInputStream = InstallFiles.class.getResourceAsStream(resourceName);
if(resourcesInputStream == null){
throw new Exception("Cannot get resource \"" + resourceName + "\" from Jar file.");
}
//Write the data from jar's resource to system file
int readBytes;
byte[] buffer = new byte[4096];
resourcesOutputStream = new FileOutputStream(outputLocation + resourceName);
while ((readBytes = resourcesInputStream.read(buffer)) > 0) {
resourcesOutputStream.write(buffer, 0, readBytes);
}
} catch (Exception ex) {
ex.printStackTrace();
System.exit(1);
} finally {
//Close streams
resourcesInputStream.close();
resourcesOutputStream.close();
}
}
Stack Trace:
java.lang.Exception: Cannot get resource "/textures\gameIcon.png" from Jar file.
All help is appreciated! Thanks
Stack Trace:
java.lang.Exception: Cannot get resource "/textures\gameIcon.png" from Jar file.
The name if the resource is wrong. As the Javadoc of ClassLoader.getResource(String) describes (and Class.getResourceAsStream(String) refers to ClassLoader for details):
The name of a resource is a /-separated path name that identifies
the resource.
No matter whether you get your resources from the File system or from a Jar File, you should always use / as the separator.
Using \ may sometimes work, and sometimes not: there's no guarantee. But it's always an error.
In your case, the solution is a change in the way that you invoke exportResource:
String path = file.getPath().substring(installFilesLocationOnDisk.length());
exportResource("/" + path.replace(File.pathSeparatorChar, '/'));
Rename your JAR file to ZIP, uncompress it and check where did resources go.
There is a possibility you're using Maven with Eclipse, and this means exporting Runnable JAR using Eclipse's functionality won't place resources in JAR properly (they'll end up under folder resources inside the JAR if you're using default Maven folder names conventions).
If that is the case, you should use Maven's Assembly Plugin (or a Shade plugin for "uber-JAR") to create your runnable JAR.
Even if you're not using Maven, you should check if the resources are placed correctly in the resulting JAR.
P.S. Also don't do this:
.getPath().replace('\\', '/');
And never rely on particular separator character - use java.io.File.separator to determine system's file separator character.
I have been trying to read a file into Eclipse. I've looked over other questions, but those answers did not remedy the situation (refreshing the project folder, using getProperty and specifying the correct path, etc.) I've moved the file into every folder and I get the same error. I've copied the file into the directory as shown here:
I've also pasted the code below. It's stupidly simple. The error I get is "FileInputStream.open(String) line: not available [native method]".
Any help would be appreciated. Code is below.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
import java.util.StringTokenizer;
public class Modulo {
public static void main(String[] args) throws FileNotFoundException {
File questions = new File("input.txt");
Scanner sc = new Scanner(questions);
while(sc.hasNext()){
int x = sc.nextInt();
String divide = sc.next();
int y = sc.nextInt();
System.out.println(x % y);
}
}
}
The answer depends.
If you want the file to be embedded within your application when your deploy it (as a Jar file for example), then you can't use File to reference it, as you've tried to include it within your application.
Eclipse further complicates the matter, as you can't included resources within your src directory, but needs to be maintained within a resources directory at the same level as your src folder (this folder may need to be included as part of your build process, but I only have a passing knowledge of how Eclipse works)...
Once you've corrected for all this, you will then need to use Class#getResource to load the resource...for example...
try (InputStream is = Modulo.class.getResourceAsStream("/input.txt")) {
Scanner sc = new Scanner(is);
//...
} catch (IOException exp) {
exp.printStackTrace();
}
However, if you want the file to be an external resource to your program, then you need to place it within a location relative to the location that the program is executed.
Normally, I would suggest the project directory, but I have a funny feeling that Eclipse run's it's Java programs in a different location ... and I don't know if you can change it...
In this case, you could use System.out.println(new File(".").getAbsolutePath()); or System.out.println(new File(".").getCanonicalPath()); or System.out.println(System.getProperty("user.dir")); which will tell you where you program is currently running and place the file there.
Of course, once build (into a Jar) you would need to place the file within a context that was relative to the location it was executed from...
You copy that file into Project folder parallel to src. This is the place base path of your code.
Eclipse by default looks for the file in the main project directory in your case Remainders, if your file is not there, you get an exception. Try placing the file directly under your project and run the same program, it should run correctly.
Hi i have exported my java project as executable jar file. inside my project I am accessing a Excel file containing some data. Now I am not able to access the Excel file when I am trying to access the file.
My project structure is:
Java_Project_Folder
- src_Folder
- resources_Folder(Containing excel file)
I am accessing the excel file like
FileInputStream file=new FileInputStream(new File(System.getProperty("user.dir")
+File.separator+"resources"+File.separator+"Excel.xlsx"));
I have tried accessing this file using getResourceAsStream like:
FileInputStream file=(FileInputStream) this.getClass().getResourceAsStream
("/resources/Excel.xlsx");
But i am getting in is null exception. whats wrong can anyone help?
I bet you have no package called resources in your project.
Trying to use Class.#getResourceAsStream is the way to go. But this method does not return a FileInputStream. It returns an InputStream wich is an interface.
You should be passing the absolute name of the resource
InputStream is = getClass().getResourceAsStream("my/pack/age/Excel.xlsx");
where the excel file is located in the directory
resources/my/pack/age
The first step is to include the excel file itself in your project. You can create a resources folder like you show, but to make sure this gets included in your jar, you add the resources folder in along with your source code files so that it gets built into the jar.
Then
InputStream excelContent = this.getClass().getResourceAsStream("/resources/Excel.xlsx");
should work. From one post at least, the leading forward slash may also mess things up if you use the ClassLoader.
getClass().getResourceAsStream("/a/b/c.xml") ==> a/b/c.xml
getClass().getResourceAsStream("a/b/c.xml") ==> com/example/a/b/c.xml
getClass().getClassLoader().getResourceAsStream("a/b/c.xml") ==> a/b/c.xml
getClass().getClassLoader().getResourceAsStream("/a/b/c.xml") ==> Incorrect
ref: getResourceAsStream fails under new environment?
Also in eclipse you can set the resources folder as a source folder like this:
in the properties of your eclipse project, go to java build path, select sources, and check to see if all needed source fodlers are added (as source folders). If some are missing, just add them manually using add sources... button
ref: Java Resources Folder Error In Eclipse
I tried this and it is working for me.
My Test1 class is in default package, just check where your accessing class is in any package, if it is then go back to exact resource folder from classpath like this "../"
public class Test1 {
public static void main(String[] args) {
new Test1();
}
Test1(){
BufferedInputStream file= (BufferedInputStream) this.getClass().getResourceAsStream("resources/a.txt");
try {
System.out.println((char)file.read());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
FileInputStream file= (FileInputStream)
this.getClass().getResourceAsStream("/resources/Excel.xlsx");
Why do you need FileInputStream? Use
InputStream is = getClass().getResourceAsStream..
Secondly use "resources/Excel.xlsx"
Thirdly when constructing file like this
new
File(System.getProperty("user.dir")+File.separator+"resources"+File.separator+"Excel.xlsx"));
is hard to control slashes. use
new File("parent (userdir property)", "child (resources\Excel.xlsx)")