Simple program throws FileNotFound Exception for relative path - java

A dumb question, but after a lot of googling, I still can't get it to work.
System.out.print("Start");
File file = new File("TestFile.txt");
Scanner scanner = new Scanner(file);
When I run this, I get a FileNotFound exception. I'm running on NetBeans, and I have placed the TestFile.txt inside the same package as the main class. When I use the absolute path, it works. I can see the see the file next to the .class file inside the build folder. I've tried using the command line, and it doesn't work either.

Relative file paths are not relative to the location of the class file containing the code. They're relative to the directory from which the java executable is started.
Just like, when executing
ls foo
or
dir foo
ls/dir look for the foo directory in the current directory, and not in the directory where the ls executable or dir executable is located.
So, similarly, when executing
java com.foo.bar.MainClass
if the MaiClass file opens the file "foo.txt", it will look for it in the directory where you were when executing the command java com.foo.bar.MainClass.

If you use relative paths the folder that has the file must be in the classpath, so you can put the file in the root folder (if you run the code from a jar file), or add the root folder to your classpath.
If you want to keep the file in that folder you have to include it into the classpath in order to get it work.
Also, the relative path for a java command line program is the root folder, so you can construct the relative path from that point too.

You should put the text file in the 'working directory' of your application. And if you don't want to do that, you should include the folder that contains this file in class path.

Related

Java can't get relative path for file

Image DescriptionTrying to access a test.txt file that is in the same location as my HelloController.java file but for some reason, it is showing that the file does not exist. I've tried moving the file around but it does not work.
Using the absolute path works, but this is a shared project so it will be ran on other computers. Any suggestions would be much appreciated.
Your best bet is to add it to the class path and reading it as a class path resource.
The relative path root is your "working directory". Which means if you try to access "." you will start at your working directory. This directory is only set once for your application and is normally the folder which was opened when you started it.
When working with IDEs (like in your case) the working directory will be the root folder of your project (So the folder in which the pom.xml and src folders are located.
If you want to access the file via the normal file API you are currently using, just put the file in that diretory and it should work (given you share it with the other people in the same location).
If you need the file to be inside your generated output jar-file, you will need to use the File as a resource (See duffymo's answer), as the file does not exist by itself on the file system, but as a file inside your jar-file.
If you want to know your current working directory, you can create a File refrence to "." and expand it to an absolute path (Which will replace refrences like "." and ".." and generate a file path from your root) and then write it to the console. This would look something like this:
// Get refrence to the current working directory
File workingDirectoryReference = new File(".");
// Convert it to an absolute path string
String absolutePath = workingDirectoryReference.getAbsolutePath();
// Output to console
System.out.println(absolutePath );

File relative to jar using Spring

I work on a Java console application. There is a property in my application.properties file, which contains another file name as a value of a property, like
my.file.location=file:myDir/myFileName
In the code I try to get the file like this:
#Value("${my.file.location}")
private File myfileLocation;
If I start the application from the directory, which contains jar file, the file is resolved, but when I run my application from a different location, the file location is not valid.
I can't have this file on classpath, it must be external to the jar file.
How can I make the file path to be relative to my jar file and not to the current working directory?
I believe this has nothing to do with Spring right? You just want to load configuration file, that is inside your application, unpacked, so the user can modify it, ok?
First, you may try to always setup the working directory, which I believe is more "standard" solution. In windows you can make a link, that specifies the Start in section and contains the path to your jar file (or bat or cmd, whatever).
If you insist on using the jar path, you could use How to get the path of a running JAR file solution. Note, that the jar must be loaded from filesystem:
URI path = MySpringBean.class.getProtectionDomain().getCodeSource().getLocation().toURI();
File myfileLocation = new File(new File(path).getParent(), "/myDir/jdbc.properties");

Access a file from a JAR in the same folder

I need to acces (create and read) a file from a JAR file (executable jar),
and that file should be created in the same directory as the JAR
I tried
this.getClass().getResource("myFile")
but since the jar has packages in it, it won't work..
I also tried write just
File f = new File("myFile");
f.createNewFile();
and that works if i execute the JAR from the terminal, but if i execute the JAR by double-clicking it, the file is created in my home directory -.-''
how do i access a file being SURE that that file is in the SAME directory as the JAR file?
(of course also getting the jar absolute path would do the trick since i can get the parent folder from it)
This will give you the full path to the Jar:
String path = this.getClass().getProtectionDomain().getCodeSource().getLocation().getPath();
EDIT: sorry, was in javascript mode when I wrote that :). As was so politely requested, in a static method you should be able to do this:
String path = Me.class.getProtectionDomain().getCodeSource().getLocation().getPath();
(where the class name is Me).

Java JAR: Writing to a file

Currently, in my eclipse project, I have a file that I write to. However, I have exported my project to a JAR file and writing to that directory no longer works. I know I need to treat this file as a classpath resource, but how do I do this with a BufferedWriter?
You shouldn't have to treat it as a classpath resource to write to a file. You would only have to do that if the file was in your JAR file, but you don't want to write to a file contained within your JAR file do you?
You should still be able to create and write to a file but it will probably be relative to the working directory - the directory you execute your JAR file from (unless you use an absolute path). In eclipse, configure the working directory from within the run configuration dialog.
You're probably working in Linux. Because, in Linux, when you start your application from a JAR, the working directory is set to your home folder (/home/yourname/). When you start it from Eclipse, the working directory is set to the project folder.
To make sure you really know the files you are using are located in the project folder, or the folder where your JAR is in, you can use this piece of code to know where the JAR is located, then use the File(File parent, String name) constructor to create your files:
// Find out where the JAR is:
String path = YourClass.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath();
path = path.substring(0, path.lastIndexOf('/')+1);
// Create the project-folder-file:
File root = new File(path);
And, from now on, you can create all your File's like this:
File myFile = new File(root, "config.xml");
Of course, root has to be in your scope.
Such resources (when altered) are best stored in a sub-directory of user.home. It is a reproducible path that the user should have write access to. You might use the package name of the main class as a basis for the sub-directory. E.G.
our.com.Main -> ${user.home}/our/com/

How to specify filepath in java?

I have created a java application for "Debian Linux." Now I want that that application reads a file placed in the directory where the jar file of that application is specified. So what to specify at the argument of the File Object?
File fileToBeReaded = new File(...);
What to specify as argument for the above statement to specify relative filepath representing the path where the jar file of the application has been placed?
If you know the name of the file, of course it's simply
new File("./myFileName")
If you don't know the name, you can use the File object's list() method to get a list of files in the current directory, and then pick the one you want.
Are you asking about escape character issues?
If that is the case then use forward slashes instead of backward slashes like
"C:/Users/You/Desktop/test.txt"
instead of
"C:\Users\You\Desktop\test.txt"
Using relative paths in java.io.File is fully dependent on the current working directory. This differs with the way you execute the JAR. If you're for example in /foo and you execute the JAR by java -jar /bar/jar/Bar.jar then the working directory is still /foo. But if you cd to /bar/jar and execute java -jar Bar.jar then the working directory is /bar/jar.
If you want the root path where the JAR is located, one of the ways would be:
File root = new File(Thread.currentThread().getContextClassLoader().getResource("").toURI());
This returns the root path of the JAR file (i.o.w. the classpath root). If you place your resource relative to the classpath root, you can access it as follows:
File resource = new File(root, "filename.ext");
Alternatively you can also just use:
File resource = new File(Thread.currentThread().getContextClassLoader().getResource("filename.ext").toURI());
I think this should do the trick:
File starting = new File(System.getProperty("user.dir"));
File fileToBeRead = new File(starting,"my_file.txt");
This way, the file will be searched in the user.dir property, which will be your app's working directory.
You could ask your classloader to give you the location of the jar:
getClass().getProtectionDomain().getCodeSource().getLocation().getPath();
...but I'd suggest to put the file you are looking for inside your jar file and read it as a resource (getClass().getResourceAsStream( "myFile.txt" )).
On IntelliJIDEA right click on the file then copy the absolute path, then in the double quotation paste the path as filePath.
for example it should be something like this:
"C:\\Users\\NameOfTheComputerUser\\IdeaProjects\\NameOfTheProject\\YourSubFolders\\name-of-the-file.example"

Categories