There is an idea of the current working directory associated with every process on a computer. When a process starts, it usually has a current working directory. This applies to the JVM process (the process that starts when you run the command java
on your computer) as well.
The relative paths that you specify in various IO class methods are with respect to this current working directory. Here's what the Javadoc of java.io.File
says:
By default the classes in the java.io package always resolve relative
pathnames against the current user directory. This directory is named
by the system property user.dir, and is typically the directory in
which the Java virtual machine was invoked.
So, what is important is to use the correct working directory when you invoke java
. Relative paths (like your file.txt
) are those that do not begin with a leading '/' or a drive letter.
Here is an example:
Foo.java
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class Foo {
public static void main(String[] args) throws IOException {
try (BufferedReader reader = new BufferedReader(new FileReader("Foo.java"))) {
System.out.println(reader.readLine());
}
}
}
This class, when run, will try to find Foo.java
itself and output its first line, which is: import java.io.BufferedReader;
.
- Compile this to
Foo.class
.
- Say, folder where
Foo.class
is stored on your (Linux) computer is /tmp
.
- You are now on a terminal in
/tmp
=> java Foo
.This should print the first line as expected.
cd $HOME
.
java -cp /tmp Foo
(this is because your class is still in /tmp)
This fails with:
Exception in thread "main" java.io.FileNotFoundException: Foo.java (No
such file or directory) at java.io.FileInputStream.open0(Native
Method) at java.io.FileInputStream.open(FileInputStream.java:195) at
java.io.FileInputStream.(FileInputStream.java:138) at
java.io.FileInputStream.(FileInputStream.java:93) at
java.io.FileReader.(FileReader.java:58) at
Foo.main(Foo.java:10)
This is because it tries to find Foo.java
in current working directory, which is $HOME
and Foo.java
itself is in some other folder (/tmp
). What is true of BufferedReader
is also true of BufferedWriter
in your case.
So, you should run this program from a folder where file.txt
resides:
cd project/out
java -cp myjar.jar Main
A better idea is to always know the location of the file you want to write to. That way, your program may get tied to a particular path on a particular type of computer, but at least you can run it from anywhere on that computer without problems.