やりたいこと
Javaで相対パス(絶対パスでもOK)から絶対パスを取得したい
File#getAbsolutePath()を使うと期待通りの結果になりませんでした。
最終的には、以下のコードで期待通りの結果になりました。
(relativePathの型はString)
Paths.get(relativePath).toRealPath(LinkOption.NOFOLLOW_LINKS).toString()
どういう場合がうまくいかないのか、そしてその解決方法を書きたいと思います
カレントディレクトリ
以下のディレクトリがカレントディレクトリです
/Users/nwtgck/IdeaProjects/getCanonicalPath test/
getAbsolutePathでもOKな場合
以下のような相対パス("out/production")であれば、File#getAbsolutePath()でも期待通りの結果になります
relativePath = "out/production";
System.out.println(new File(relativePath).getAbsolutePath());
出力
/Users/nwtgck/IdeaProjects/getCanonicalPath test/out/production
getAbsolutePathの予想外1の結果
relativePath = "..";
System.out.println(new File(relativePath).getAbsolutePath());
出力
/Users/nwtgck/IdeaProjects/getCanonicalPath test/..
相対パスが「..」なので、出力が親ディレクトリの"/Users/nwtgck/IdeaProjects"になることを期待しましたが、なりません。
「..」で親ディレクトリの絶対パスを取得する
File#getgetCanonicalPath()を使うと期待通りに取得できます
relativePath = "..";
System.out.println(new File(relativePath).getCanonicalPath());
出力
/Users/nwtgck/IdeaProjects
基本的にはgetCanonicalPath()でOKですが、relativePath
がシンボリックリンクの時はリンク先のパスになってしまいます。
シンボリックリンクでも絶対パスを取得する
relativePath = "/Users/nwtgck/Desktop/link";
System.out.println(Paths.get(relativePath).toRealPath(LinkOption.NOFOLLOW_LINKS));
出力
/Users/nwtgck/Desktop/link
シンボリックリンクでもそのファイル自体のパスになりました
-
仕様ですが、個人的には予想外でした ↩