Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why a Java file exists only in its canonical form?

Tags:

java

I'm facing a strange behaviour of the JVM. I wanted to change the user directory, i.e. the dir where files are looked up, that normally corresponds to the path where the java command is run.

So I wrote the following code:

System.setProperty("user.dir", "/tmp/");
File f = new File("myfile");
System.out.println(f.exists());
System.out.println(f.getCanonicalFile().exists());

The file /tmp/myfile exists and is readable by the JVM, but if I'm not in /tmp/ when I run that code, the result is:

false
true

They are the same file, Java is able to retrieve the correct canonical form of it, but the relative one does not exist, while the canonical one exists.

Is it a bug? Is there a way to reliably change the JVM user directory?

Changing the code is not an option, as I'm trying to run external libraries.

like image 605
Nicola Ferraro Avatar asked Jun 20 '16 08:06

Nicola Ferraro


People also ask

What is the existence of Java code file?

The exists() function is a part of the File class in Java. This function determines whether the is a file or directory denoted by the abstract filename exists or not. The function returns true if the abstract file path exists or else returns false. Parameters: This method does not accept any parameter.

What is the difference between absolute path and canonical path in Java?

A canonical path is always an absolute path. Converting from a path to a canonical path makes it absolute (usually tack on the current working directory so e.g. ./file. txt becomes c:/temp/file. txt ).

What is canonical path in Java?

The canonical path is always an absolute and unique path. If String pathname is used to create a file object, it simply returns the pathname. This method first converts this pathname to absolute form if needed. To do that it will invoke the getAbsolutePath() Method and then maps it to its unique form.

Is an example for representing the file path in the canonical form?

For example, "/var/tmp/foo" is a canonical path while "/var/tmp/foo/" is not.


1 Answers

This behavior is normal, the reason is, there is a difference between

File f = new File("myfile");

and

File cf = new File("myfile").getCanonicalFile();

The first denotes a filepath relative to your current WORKING DIR, which could be your project path. Using the relative path, the user.dir property is NOT USED, even when setting user.dir as JVM parameter -Duser.dir=/tmp/. The resolution of Java file handles to native file entities is done natively by the underlying Fileystem implementation.

But when invoking getCanoncialFile() before resolving the native file handle the relative path is resolved using the user path information - in your case user.dir = /tmp/.

Apparently, there is no file myfile in <WORKING_DIR> but in /tmp/.

The behavior is the same for f.getAbsoluteFile().

like image 86
Gerald Mücke Avatar answered Sep 30 '22 09:09

Gerald Mücke