Reputation: 12837
Here is the problem. I have a symlink pointing to some other directory:
$ls -l /foo/bar
lrwxrwxrwx /foo/bar -> /target/bar
in the foo
directory there is a file x
$ls -l /foo
lrwxrwxrwx me me 314 x
Now, I want to have an access to x
by the following path /foo/bar/../x
$ls -l /foo/bar/../x : No such file or directory
This doesn't work in Bash, but is there any way to make it work from Java using the File api? The directory structure can be pretty much arbitrary so there might be cases like /foo/bar/1/2/3/4/5/../../../../../../x
, etc.
In other words I am looking for the content of the magic()
method checking the existence of a file (assuming the previously mentioned directory structure):
magic("/foo/x") ... true
magic("/foo/bar/../x") ... true
magic("/foo/bar/1//../../x") ... true
magic("/foo/bar/1/2/3/4/5/../../../../../../x") ... true
magic("/foo/bar//1/../2/../../x") ... true
magic("/foo/bar/1/2/../3/../../../x") ... true
magic("/foo/bar/1/2/./../3/../4//../../../x") ... true
magic("/foo/bar/x") ... false
magic("/foo/bar/1/../x") ... false
magic("/foo/bar/1/2/3/4/../../../../../../x") ... false
magic("/foo/bar//1/../2/../x") ... false
NOTE 1: getCanonicalPath() doesn't work for me, because it firstly resolves the symlinks and then all the ".." or "." in path. I need it to be done vice-versa.
NOTE 2: There might me other symlinks in the path and it should work in the same sense (dir 2
may be a symlink).
NOTE 3: The file x
is located only in the /foo
.
So far, it looks like I need a parser for context-free grammar, isn't there any easier solution to this problem?
Upvotes: 2
Views: 966
Reputation: 19
Path is a Java7 API. If you're stuck with Java6, I think the following would fit the bill, too: http://commons.apache.org/proper/commons-io/javadocs/api-1.4/org/apache/commons/io/FilenameUtils.html#normalize%28java.lang.String%29
Upvotes: 0
Reputation: 11433
If I understand you correctly, the Path.normalize()
method should be doing exactly what you want?
It eliminates ..
(among other things), and it's documentation says
This method does not access the file system; the path may not locate a file that exists. Eliminating ".." and a preceding name from a path may result in the path that locates a different file than the original path. This can arise when the preceding name is a symbolic link.
You don't need to resolve the other symlinks on the path, the OS will resolve them when you try to access the file in the end. If you want to resolve the symlinks anyway, call Path.toRealPath()
afterwards (not giving NOFOLLOW_LINKS
as argument).
Upvotes: 4