LoginSignup
16
17

More than 5 years have passed since last update.

Javaで絶対パスを取得するgetAbsolutePath()の罠と解決方法

Last updated at Posted at 2015-09-18

やりたいこと

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

シンボリックリンクでもそのファイル自体のパスになりました


  1. 仕様ですが、個人的には予想外でした 

16
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
17