I am trying to read a file from my executable .jar file but it keeps getting null values.
I have this code:
public DanceEventTicketScanner(String txtfile){
sv = new ScannerView(this);
findcode = false;
InputStream is = this.getClass().getResourceAsStream("/resources/copy.csv");
if (is == null) JOptionPane.showMessageDialog(null, "Resource not located.");
}
In the JAR file i have (as normal) a folder containing all my .class files and in the same directory a folder named resources which holds the copy.csv file.
This code however does not recognize the file.
Does anyone have any ideas?
Remove the first slash:
InputStream is = this.getClass().getResourceAsStream("resources/copy.csv");
getClass().getResourceAsStream(..) will use a path relative to the class (so inc. package dirs). getClass().getClassLoader().getResourceAsStream(..) will use an absolute path. So change your code and get the class loader and it will work.
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");
I'm just trying to read in a simple .txt file into my java project using this.class.getResourceAsStream(filename). I have several files within main/resources, and almost all of them return an object when I try to get them as an input stream. The only object I can't read in is my text file.
I have placed the file with all of the other resource files that are readable by the classloader, but it appears this file wasn't placed in the class' classLoader for whatever reason. If I unzip the jar, the file is still included with the jar in the same directory as all of the other resources, so it seems to be being built correctly.
I guess what I'm asking is at what point do I tell Java what files I want to be included as a resource in a class' ClassLoader? Is it something that should be done when the jar is built if things are in the correct place (i.e main/resources)?
Here is what the code looks like, and it's respective return values, when running for the file it can find and the file it can't, that are both located in the same place.
// This is not found. Both are placed at src/main/resources
def tmpDict = this.class.getResourceAsStream("dict.txt")
println tmpDict // null
// This is found
def tmpDict2 = this.class.getResourceAsStream("calc.config")
println tmpDict2 // sun.net.www.protocol.jar.JarURLConnection$JarURLInputStream#2dae5a79
Without more info i'd say the path is wrong. when i used just "file.txt" for the path it got NPE
i used this method to read from the stream. The file was located at \src\main\resources\static\file.txt
This worked in eclipse, packaged into jar and worked there too.
public String getFile() throws Exception {
InputStream in = Controller.class.getClassLoader().getResourceAsStream("static/file.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(in, Charset.defaultCharset()));
StringBuilder out = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
out.append(line);
}
return out.toString();
}
Some very Basic checks:
The file must be case-sensitive (as it is not a Windows file), and special characters of the file name might be cumbersome. Also check that the file in your project has the file extension not twice (.txt.txt - Windows hiding the extension).
Check that getResourceAsStream("/a/b/c/A.txt") indeed gives a null.
If not the reading might go wrong on the encoding.
I have a file named "word.txt".
It is in the same directory as my java file.
But when I try to access it in the following code this file not found error occurs:
Exception in thread "main" java.io.FileNotFoundException: word.txt
(The system cannot find the file specified)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.<init>(Unknown Source)
at java.util.Scanner.<init>(Unknown Source)
at Hangman1.main(Hangman1.java:6)
Here's my code:
import java.io.File;
import java.util.*;
public class Hangman1 {
public static void main(String[] args) throws Exception {
Scanner input = new Scanner(new File("word.txt"));
String in = "";
in = input.nextLine();
}
}
Put the word.txt directly as a child of the project root folder and a peer of src
Project_Root
src
word.txt
Disclaimer: I'd like to explain why this works for this particular case and why it may not work for others.
Why it works:
When you use File or any of the other FileXxx variants, you are looking for a file on the file system relative to the "working directory". The working directory, can be described as this:
When you run from the command line
C:\EclipseWorkspace\ProjectRoot\bin > java com.mypackage.Hangman1
the working directory is C:\EclipseWorkspace\ProjectRoot\bin. With your IDE (at least all the ones I've worked with), the working directory is the ProjectRoot. So when the file is in the ProjectRoot, then using just the file name as the relative path is valid, because it is at the root of the working directory.
Similarly, if this was your project structure ProjectRoot\src\word.txt, then the path "src/word.txt" would be valid.
Why it May not Work
For one, the working directory could always change. For instance, running the code from the command line like in the example above, the working directory is the bin. So in this case it will fail, as there is not bin\word.txt
Secondly, if you were to export this project into a jar, and the file was configured to be included in the jar, it would also fail, as the path will no longer be valid either.
That being said, you need to determine if the file is to be an embedded-resource (or just "resource" - terms which sometimes I'll use interchangeably). If so, then you will want to build the file into the classpath, and access it via an URL. First thing you would need to do (in this particular) case is make sure that the file get built into the classpath. With the file in the project root, you must configure the build to include the file. But if you put the file in the src or in some directory below, then the default build should put it into the class path.
You can access classpath resource in a number of ways. You can make use of the Class class, which has getResourceXxx method, from which you use to obtain classpath resources.
For example, if you changed your project structure to ProjectRoot\src\resources\word.txt, you could use this:
InputStream is = Hangman1.class.getResourceAsStream("/resources/word.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
getResourceAsStream returns an InputStream, but obtains an URL under the hood. Alternatively, you could get an URL if that's what you need. getResource() will return an URL
For Maven users, where the directory structure is like src/main/resources, the contents of the resources folder is put at the root of the classpath. So if you have a file in there, then you would only use getResourceAsStream("/thefile.txt")
Relative paths can be used, but they can be tricky. The best solution is to know where your files are being saved, that is, print the folder:
import java.io.File;
import java.util.*;
public class Hangman1 {
public static void main(String[] args) throws Exception {
File myFile = new File("word.txt");
System.out.println("Attempting to read from file in: "+myFile.getCanonicalPath());
Scanner input = new Scanner(myFile);
String in = "";
in = input.nextLine();
}
}
This code should print the folder where it is looking for. Place the file there and you'll be good to go.
Your file should directly be under the project folder, and not inside any other sub-folder.
If the folder of your project is named for e.g. AProject, it should be in the same place as your src folder.
Aproject
src
word.txt
Try to create a file using the code, so you will get to know the path of the file where the system create
File test=new File("check.txt");
if (test.createNewFile()) {
System.out.println("File created: " + test.getName());
}
I was reading path from a properties file and didn't mention there was a space in the end.
Make sure you don't have one.
Make sure when you create a txt file you don't type in the name "name.txt", just type in "name". If you type "name.txt" Eclipse will see it as "name.txt.txt". This solved it for me. Also save the file in the src folder, not the folder were the .java resides, one folder up.
I have the same problem, but you know why? because I didn't put .txt in the end of my File and so it was File not a textFile, you shoud do just two things:
Put your Text File in the Root Directory (e.x if you have a project called HelloWorld, just right-click on the HelloWorld file in the package Directory and create File
Save as that File with any name that you want but with a .txt in the end of that
I guess your problem is solved, but I write it to other peoples know that.
Thanks.
i think it always boils to the classpath. having said that if you run from the same folder where your .class is then change Scanner input = new Scanner(new File("word.txt")); to Scanner input = new Scanner(new File("./word.txt")); that should work
I have a file dateTesting.java . the path's directory is as follows: D:\workspace\Project1\src\dateTesting.java . I want the full path of this file as "D:\workspace\Project1\src" itself but when I use any of the following code, i get only "D:\workspace\Project1" . the src part is not coming.
System.out.println(System.getProperty("user.dir"));
File dir2 = new File(".");
System.out.println(dir2.getCanonicalPath().toString());
System.out.println(dir2.getAbsolutePath());
How can I get the full path as "D:\workspace\Project1\src" ? I'm using eclipse ide 3.5
Thank you
dateTesting.java is a Java source file which is not available after compilation to bytecode. The source directory it was in is not available, too.
dir2 is the File of the directory you execute the .class file in. It seams that this happens to be D:\workspace\Project1 but you can't rely on this.
Your dir2 points to working directory (new File(".")). You can't get the location of your sources this way. Your file could sit inside the package (e.g. your.company.date.dateTesting). You should just manually concat the "src" to current working directory and then replace file package dots (.) with File.pathSeparator. In that way you will build the full path to your file.
String fullFilePath = "H:\\Shared\\Testing\\abcd.bmp";
File file = new File(fullFilePath);
String filePath = file.getAbsolutePath().substring(0,fullFilePath.lastIndexOf(File.separator));
System.out.println(filePath);
Output:
H:\Shared\Testing
If you are doing this to try to read a file from the classpath, then check out this answer:
How to really read text file from classpath in Java
Essentially you can do this
InputStream in = this.getClass().getClassLoader()
.getResourceAsStream("SomeTextFile.txt");
Otherwise, if you have some other requirement, one option is to pass through the src directory as a JVM arg when the application begins and then just read it back.
/** The actual file running */
public static final File JAR_FILE = new File(MyClass.class.getProtectionDomain().getCodeSource().getLocation().getPath();
/** The path to the main folder where the file .jar is run */
public static final String BASE_DIRECTORY = (JAR_FILE != null ? JAR_FILE.getAbsolutePath().replace(JAR_FILE.getName(), "") : "notFound");
This will work for you both in normal java execution and jar execution. This is the solution I am using in my project.
I am making a program that opens and reads a file.
This is my code:
import java.io.*;
public class FileRead{
public static void main(String[] args){
try{
File file = new File("hello.txt");
System.out.println(file.getCanonicalPath());
FileInputStream ft = new FileInputStream(file);
DataInputStream in = new DataInputStream(ft);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strline;
while((strline = br.readLine()) != null){
System.out.println(strline);
}
in.close();
}catch(Exception e){
System.err.println("Error: " + e.getMessage());
}
}
}
but when I run, I get this error:
C:\Users\User\Documents\Workspace\FileRead\hello.txt
Error: hello.txt (The system cannot find the file specified)
my FileRead.java and hello.txt where in the same directory that can be found in:
C:\Users\User\Documents\Workspace\FileRead
I'm wondering what I am doing wrong?
Try to list all files' names in the directory by calling:
File file = new File(".");
for(String fileNames : file.list()) System.out.println(fileNames);
and see if you will find your files in the list.
I have copied your code and it runs fine.
I suspect you are simply having some problem in the actual file name of hello.txt, or you are running in a wrong directory. Consider verifying by the method suggested by #Eng.Fouad
You need to give the absolute pathname to where the file exists.
File file = new File("C:\\Users\\User\\Documents\\Workspace\\FileRead\\hello.txt");
In your IDE right click on the file you want to read and choose "copy path"
then paste it into your code.
Note that windows hides the file extension so if you create a text file "myfile.txt" it might be actually saved as "myfile.txt.txt"
Generally, just stating the name of file inside the File constructor means that the file is located in the same directory as the java file. However, when using IDEs like NetBeans and Eclipse i.e. not the case you have to save the file in the project folder directory. So I think checking that will solve your problem.
How are you running the program?
It's not the java file that is being ran but rather the .class file that is created by compiling the java code. You will either need to specify the absolute path like user1420750 says or a relative path to your System.getProperty("user.dir") directory. This should be the working directory or the directory you ran the java command from.
First Create folder same as path which you Specified. after then create File
File dir = new File("C:\\USER\\Semple_file\\");
File file = new File("C:\\USER\\Semple_file\\abc.txt");
if(!file.exists())
{
dir.mkdir();
file.createNewFile();
System.out.println("File,Folder Created.);
}
When you run a jar, your Main class itself becomes args[0] and your filename comes immediately after.
I had the same issue: I could locate my file when provided the absolute path from eclipse (because I was referring to the file as args[0]). Yet when I run the same from jar, it was trying to locate my main class - which is when I got the idea that I should be reading my file from args[1].