I am trying to understand the way Java resolves relative path in while creating a File
object.
OS used: Windows
For the below snippet, I am getting an IOException
as it cannot find the path:
@Test public void testPathConversion() { File f = new File("test/test.txt"); try { f.createNewFile(); System.out.println(f.getPath()); System.out.println(f.getAbsolutePath()); System.out.println(f.getCanonicalPath()); } catch (Exception e) { e.printStackTrace(); } }
My understanding here is, Java treats the path provided as absolute and returns an error when the path does not exist. So it makes sense.
When I update the above code to use relative path:
@Test public void testPathConversion() { File f = new File("test/../test.txt"); try { f.createNewFile(); System.out.println(f.getPath()); System.out.println(f.getAbsolutePath()); System.out.println(f.getCanonicalPath()); } catch (Exception e) { e.printStackTrace(); } }
It creates a new file and provides the below output:
test\..\test.txt C:\JavaForTesters\test\..\test.txt C:\JavaForTesters\test.txt
In this case, my assumption is, even though the path provided doesn't exist, because the path contains "/../", java treats this as a relative path and creates the file in the user.dir
. So this also makes sense.
But if I update the relative path as below:
@Test public void testPathConversion() { File f = new File("test/../../test.txt"); try { f.createNewFile(); System.out.println(f.getPath()); System.out.println(f.getAbsolutePath()); System.out.println(f.getCanonicalPath()); } catch (Exception e) { e.printStackTrace(); } }
Then I get IOException: Access is denied.
My questions are:
"test/../test.txt"
is treated as a relative path and creates the file in "user.dir"
but"test/../../test.txt"
returns an error? Where does it attempt to create the file for the path "test/../../test.txt"
?When the specified relative path is not found, the file seems to be created in the user.dir
. So, it appears to me that the below two scenarios does the same thing:
//scenario 1 File f = new File("test/../test.txt"); f.createNewFile(); //scenario 2 File f = new File("test.txt"); f.createNewFile();
So is there a real world case where one would use scenario 1 instead of scenario 2?
I suppose I am missing something obvious here or have fundamentally misunderstood relative paths. I went through the Java docs for File and I am not able to find an explanation for this. There are quite a few questions posted in Stack Overflow regarding relative paths, but the ones I looked up were for specific scenarios and not exactly about how relative paths are resolved.
It will be great if someone could please explain me how this works or point to some related links?
A relative path refers to a location that is relative to a current directory. Relative paths make use of two special symbols, a dot (.) and a double-dot (..), which translate into the current directory and the parent directory. Double dots are used for moving up in the hierarchy.
resolve(String other) method of java. nio. file. Path used to converts a given path string to a Path and resolves it against this Path in the exact same manner as specified by the resolve method.
There is a concept of a working directory
.
This directory is represented by a .
(dot).
In relative paths, everything else is relative to it.
Simply put the .
(the working directory) is where you run your program.
In some cases the working directory can be changed but in general this is
what the dot represents. I think this is C:\JavaForTesters\
in your case.
So test\..\test.txt
means: the sub-directory test
in my working directory, then one level up, then the
file test.txt
. This is basically the same as just test.txt
.
For more details check here.
http://docs.oracle.com/javase/7/docs/api/java/io/File.html
http://docs.oracle.com/javase/tutorial/essential/io/pathOps.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With