How Does Java Resolve a Relative Path in New File()

How does Java resolve a relative path in new File()?

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

Java Resolve Relative Path

The general way is to use the File class getCanonicalPath() method.

It's specifically documented to remove (resolve) the ../ and ./ that you're looking for.

Extracts from the docs:

This method first converts this pathname to absolute form if necessary [...] and then maps it to its unique form in a system-dependent way. This typically involves removing redundant names such as "." and ".." from the pathname, resolving symbolic links (on UNIX platforms), and converting drive letters to a standard case (on Microsoft Windows platforms).

How to read file from relative path in Java project? java.io.File cannot find the path specified

If it's already in the classpath, then just obtain it from the classpath instead of from the disk file system. Don't fiddle with relative paths in java.io.File. They are dependent on the current working directory over which you have totally no control from inside the Java code.

Assuming that ListStopWords.txt is in the same package as your FileLoader class, then do:

URL url = getClass().getResource("ListStopWords.txt");
File file = new File(url.getPath());

Or if all you're ultimately after is actually an InputStream of it:

InputStream input = getClass().getResourceAsStream("ListStopWords.txt");

This is certainly preferred over creating a new File() because the url may not necessarily represent a disk file system path, but it could also represent virtual file system path (which may happen when the JAR is expanded into memory instead of into a temp folder on disk file system) or even a network path which are both not per definition digestable by File constructor.

If the file is -as the package name hints- is actually a fullworthy properties file (containing key=value lines) with just the "wrong" extension, then you could feed the InputStream immediately to the load() method.

Properties properties = new Properties();
properties.load(getClass().getResourceAsStream("ListStopWords.txt"));

Note: when you're trying to access it from inside static context, then use FileLoader.class (or whatever YourClass.class) instead of getClass() in above examples.

.exist() - file does not exist, when using relative path

An absolute path starts from the filesystem root. Compare it to an address on a letter. The postman knows where to deliver that letter.

A relative path is not a target address. It is more like - when you see the gas station, turn left. Depending from which direction you come, you end up in various other locations.

Back to computers: relative paths are calculated based on a current working directory. You can print that from your java program by checking

How to get the current working directory in Java?

I usually write my code to be a bit clearer about the events. The following code will not only tell whether it found the file but also let you know where exactly it was searching for it.

        // File object
File myFile = new File("text1.txt");

// Prints a String, that tells you if the file exists
System.out.println("File "+myFile.getAbsolutePath()+" exists = " + myFile.exists());

How to construct a relative path in Java from two absolute paths (or URLs)?

It's a little roundabout, but why not use URI? It has a relativize method which does all the necessary checks for you.

String path = "/var/data/stuff/xyz.dat";
String base = "/var/data";
String relative = new File(base).toURI().relativize(new File(path).toURI()).getPath();
// relative == "stuff/xyz.dat"

Please note that for file path there's java.nio.file.Path#relativize since Java 1.7, as pointed out by @Jirka Meluzin in the other answer.

How to create the relative path in Java?

Relativize!

There is Path relativize(Path other)

Relativization is the inverse of resolution. This method attempts to
construct a relative path that when resolved against this path, yields
a path that locates the same file as the given path. For example, on
UNIX, if this path is "/a/b" and the given path is "/a/b/c/d" then the
resulting relative path would be "c/d". Where this path and the given
path do not have a root component, then a relative path can be
constructed. A relative path cannot be constructed if only one of the
paths have a root component. Where both paths have a root component
then it is implementation dependent if a relative path can be
constructed. If this path and the given path are equal then an empty
path is returned.

For any two normalized paths p and q, where q does not have a root
component,

p.relativize(p .resolve(q)).equals(q) When symbolic links are
supported, then whether the resulting path, when resolved against this
path, yields a path that can be used to locate the same file as other
is implementation dependent. For example, if this path is "/a/b" and
the given path is "/a/x" then the resulting relative path may be
"../x". If "b" is a symbolic link then is implementation dependent if
"a/b/../x" would locate the same file as "/a/x".

Example

Path dir = Path.of("/var/lib");
Path file = Path.of("/var/lib/someapp/1.txt");
Path relative = dir.relativize(file);
System.out.print(relative);

Output

someapp/1.txt


Related Topics



Leave a reply



Submit