java.io.FileNotFoundException: the system cannot find the file specified - java

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

Related

Jar is not loading resources file

I have a project with a folder "src/main/resources" where inside there is the hibernate configuration file, I load it using this line of code
HibernateUtil.class.getResource("/hibernate.cgf.xml").getPath()
From inside the IDE it is working well, but when I create the jar it doesn't file the file.
How can I load it properly in the jar file too?
Thanks
Could you please try this:
ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("fileName").getFile());
I cannot say for ceratin that this is the issue without knowing how exactly you use the path extracted by:
HibernateUtil.class.getResource("/hibernate.cgf.xml").getPath()
but I can tell you this:
Run from an IDE the above line of code will return:
/path/to/project/src/main/resources/hibernate.cgf.xml
which is a valid filesystem path. You can then use this path to, for example, create an instance of File class and then use that instance to read the file contents.
However the same line of code run from inside a jar file will return:
file:/path/to/jar/jar_name.jar!/hibernate.cgf.xml
which is not a valid filesystem path. If you create an instance of File class using this path and then try to read the contents of the file you'll get an exception: java.io.FileNotFoundExeption
To read the contents of the file from inside of a jar you should use method Class.getResourceAsStream(String), which will return an instance of class sun.net.www.protocol.jar.JarURLConnection.JarURLInputStream (or equivalent in non-Oracle or non-OpenJDK Java). You can then use this object to read the contents of the file. For example:
InputStream inputStream = HibernateUtil.class.getResourceAsStream("/hibernate.cgf.xml");
Scanner scanner = new Scanner(inputStream).useDelimiter("\\A");
String fileContents = scanner.hasNext() ? sscanner.next() : "";
Most likely, the file is absent from the jar you create. There's too little information in your question, but I will try a guess:
Your hibernate.cgf.xml resides in the same directory as the Java sourcefles, and you are using a build tool (be it IDE, maven, gradle or an ant script) that expects resources to be stored in a separate directory.
It's easy to check: try to unzip your jar and see if the file is there (use any tool, you can just change the extension from .jar to .zip). I think you will see the file is absent.
Then come back with a question: "how to pack my non-java resources into a jar, using XXX", where XXX will be the name of the techology you are using for building the jar.
Most probably the slash in "/hibernate.cgf.xml" is not needed, if the hibernate.cgf.xml is in the same package as you class HibernateUtil.
You can access the file actually also via the classloader using the full path. Yet you never add to it the first slash.
Here is some code demonstrating how you can access the file using different methods:
public static void main(String[] args) {
// Accessing via class
System.out.println(SimpleTests.class.getResource("hibernate.cgf.xml").getPath());
// Accessing via classloader from the current thread
String path = Thread.currentThread().getContextClassLoader()
.getResource("simple/hibernate.cgf.xml").getPath();
System.out.println(path);
// Accessing via classloader used by the current class
System.out.println(SimpleTests.class.getClassLoader().getResource("simple/hibernate.cgf.xml").getPath());
}
In the example above the package 'simple' should be replaced by the package where your hibernate.cgf.xml is. But you should never have the slash at the beginning of the package declaration.

How to get absolute path of files outside the current working directory [java]

I'm trying to read a file outside my current working directory using File and URL classes in Java. I know that the current working directory is 'represented' by a . by default.
Assuming my Java class is under /folders/Desktop/MyClass.java, if I want to read a file file1.txt in /folders/Desktop/file1.txt, I can do the following:
URL url = getClass().getResource("./file1.txt"); /* or "./anotherFolder/../file1.txt", or simply "file1.txt"*/
File f = new File(url.getPath());
and everything works as expected.
But what should I do to read a file that is not inside the current working directory and that is not inside a subdirectory of it? For example, if the file's path is /folders/file1.txt? I searched everywhere, but can't find anything. I tried ../file1.txt, ./../file1.txt and others, but nothing works. Maybe I missed something, or maybe I haven't searched in the right places.
If you don't give a path to the file name, then java is searching in the directory where the app is running.
Example:
This will print true if the file is in the main folder of the project...
public static void main(String[] args) {
final File foo = new File("asd.txt");
System.out.println(foo.exists());
}
EDit:
if the file if not in that folder then you can go "up" in the folder structure with the "./" or "../" operators...
or go deeper in the folders File("/src/asd.txt") for example is the file were inside the src folder..
If you want to access a file that is not below the current working directory you would either traverse the file system programmatically or you would get an absolute path by user input and construct the java.io.File object with new File(absolutePathAsString). You might also consider using the newer java.nio.file API.

Reading file right outside jar

So I have a .jar file in a folder and I have some input files in that folder. However, the program looks for the file in the home folder (several layers up). I want it obviously to read it from the folder that it's in but I don't want to be explicit about the file path to my folder because other people won't necessarily put their .jar file in the same spot.
Is there a way to read a file directly outside of the jar file? If not, is there a way to do this without hard-coding the file path?
edit:
here's the code. It just checks if the input files exist.
package main;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
/**
* Created by chris on 12/1/15.
* Control class that will be run when the jar is run.
*/
public class run {
public static void main(String[] args) throws Exception {
if (!(new File("settings.txt").exists())) {
start.run();
}
if (!(new File("api_key.txt").exists())) {
alert.display("Make your api_key.txt please.");
} else {
gatherData.run();
}
}
}
edit 2:
I've tried adding relative references with "./" at the beginning but that doesn't work either.
If you can rely on your .jar file being on the file system, you can get the absolute path of it by
new File(run.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath());
which can result in a SecurityException if a SecurityManager is present and not allowing this.
Another possibility would be to use
(new File(System.getProperty("java.class.path"))).getAbsolutePath();
The folder of the jar file can then be obtained using getParentFile()
If I am not wrong you are trying to access a file right in the same folder as that of the .jar file.
This can easily be done using the relative URL. By relative URL, I meant using
new File("./settings.txt"), this searches for the file in the folder same as that of the running .jar file. however you can use "../settings.txt" to look for the file one folder up.
"./" refers same directory "../" refers one directory up.
Just use ./ before file names.
The JAR files not neccesarly load from file system, and when loaded from file system can be any directory where the application start from - so relative path is not a good idea. The JAR files can from other types of source not only FileSystem, because it can be stream. I think the best way if there is a system parameter where you can pass the directory or working directory when you start the JAR file.

Eclipse-Java: where to put file for Read purpose

I'm programming Java in Eclipse IDE. Here is code I want to read file:
File file = new File("file.txt");
reader = new BufferedReader(new FileReader(file));
I put file.txt in two place:
1) same folder of this SOURCE file.
2) in bin\...\ (same folder of this CLASS file)
But I allways receive NO FILE FOUND.
Please help me.
thanks :)
If the file ships with your application, it would be better accessed as a resource than as a file. Simply copy it to somewhere in your build path and use Class.getResourceAsStream or ClassLoader.getResourceAsStream. That way you'll also be able to access it if you bundle your app as a jar file.
Currently, you're looking for the file relative to the process's current working directory, which could be entirely unrelated to where the class files are.
if you put the file under sources and inside the package "test" for example, the path is:
./src/test/file.txt
you can use
File file = new File("./src/test/file.txt");
System.out.println(file.exists());
The path ./bin/test/file.txt will work in the second case and is more suitable for a normal java project

getResource() to a file at runtime

I put some .txt files under the src folder (in the resources folder).
But I can't create a valid File at runtime from this resource.
String path = this.getClass().getResource("/resources/file.txt").getFile();
File file = new File(path);
if (!file.exists()) {
}
I run my program from eclipse. I didn't put in classpath anything.
I want my text files to be embedded into the .jar file, when I run my app I want to grab those files and copy them into some location.
UPDATE
if I do InputStream is = getClass().getResourceAsStream("/resources/file.txt");
I get the stream!!
As you already discovered yourself soon after posting your question, this works:
InputStream is = getClass().getResourceAsStream("/resources/file.txt");
The reason this works, while your original code doesn't, is because a "file" inside in a zip file (a jar file is a zip file) is not a real file until it has been extracted. But extracting the file is what you are trying to do, so at that point in your program, it's not a real file. So this question is an X-Y problem: you wanted to create a File object, but that wasn't possible - you needed to refer back to what you were originally trying to do, which was read from the zip entry.
You said that you are using eclipse, and that you dragged and dropped your text files into the "src" package. "src" is not a package. It is simply a file system directory. By default in a Java project in eclipse all your source code is stored in a directory called "src" and all your .class files are stored in a directory called "bin". getClass().getResource() resolves to the location of your .class files. You must move the text files into the "bin" directory.
What package is your class in?
I wrote very similar code to yours in the default package and ran it in eclipse.
import java.io.File;
public class ResourceTest {
public static void main(String[] args) {
ResourceTest rt = new ResourceTest();
rt.openFile();
}
public void openFile() {
String path = this.getClass().getResource("/resources/file.txt").getFile();
File file = new File(path);
System.out.println(path);
System.out.println(file.getAbsolutePath());
System.out.println(file.exists());
}
}
I see this output:
/C:/Users/rab29/Documents/eclipse/Overflow/bin/resources/file.txt
C:\Users\rab29\Documents\eclipse\Overflow\bin\resources\file.txt
true

Categories