JavaのgetPath()、getAbsolutePath()、およびgetCanonicalPath()の違いは何ですか?


583

違いは何だgetPath()getAbsolutePath()getCanonicalPath()Javaでは?

そして、それぞれをいつ使用しますか?


Path.toAbsolutePath().normalize()どちらが正規(実際の)パスと絶対パスのみの中間かということを忘れないでください。
eckes 2017年

回答:


625

次のファイル名を検討してください。

C:\temp\file.txt -これはパス、絶対パス、および正規パスです。

.\file.txt-これは道です。絶対パスでも正規パスでもありません。

C:\temp\myapp\bin\..\\..\file.txt-これはパスであり、絶対パスです。これは正規のパスではありません。

正規パスは常に絶対パスです。

パスから正規のパスに変換すると、絶対パスになります(通常、現在の作業ディレクトリにタックするため、たとえばに./file.txtなりますc:/temp/file.txt)。ファイルの正規のパスは、パスを「純粋化」し、..\シンボリックリンク(UNIXの場合)などを削除して解決します。

nio.Pathsを使用した次の例にも注意してください。

String canonical_path_string = "C:\\Windows\\System32\\";
String absolute_path_string = "C:\\Windows\\System32\\drivers\\..\\";

System.out.println(Paths.get(canonical_path_string).getParent());
System.out.println(Paths.get(absolute_path_string).getParent());

どちらのパスも同じ場所を参照していますが、出力はまったく異なります。

C:\Windows
C:\Windows\System32\drivers

11
FWIW、C:\temp\file.txt正規のパスであるとは限りません。一時ディレクトリはファイルシステムのソフトリンクまたはハードリンク(NTFSのジャンクション)であり、file.txtはソフトリンクである可能性があります。ファイルシステムがファイルへのハードリンクを区別できるかどうかはわかりません。
Lawrence Dol、

1
パスはそれらの問題やコンポーネントの存在を実際には考慮せず、その構文のみを考慮します。
escape-llc 2016

正規化されたパスとは異なり、正規のパスはファイルシステムにヒットします。
eckes 2017年

1
基本的に、のgetAbsolutePath()代わりに使用する理由がわかりませんgetCanonicalPath()。正規のものはそれらの../部分を自動的に解決するため、見栄えもよくなります。
Scadge 2018

これが考慮事項である場合getCanonicalPathIOExceptionしばらくスローしないことを忘れないでくださいgetAbsolutePath
放棄されたカート

129

このようなものを感じるために私が見つけた最良の方法は、それらを試すことです。

import java.io.File;
public class PathTesting {
    public static void main(String [] args) {
        File f = new File("test/.././file.txt");
        System.out.println(f.getPath());
        System.out.println(f.getAbsolutePath());
        try {
            System.out.println(f.getCanonicalPath());
        }
        catch(Exception e) {}
    }
}

出力は次のようになります。

test\..\.\file.txt
C:\projects\sandbox\trunk\test\..\.\file.txt
C:\projects\sandbox\trunk\file.txt

したがって、getPath()Fileオブジェクトに基づくパスを提供します。これは、相対パスである場合とそうでない場合があります。getAbsolutePath()ファイルへの絶対パスを提供します。そしてgetCanonicalPath()あなたのファイルに固有の絶対パスを提供します。同じファイルを指す絶対パスが多数ありますが、正規パスは1つしかありません。

それぞれをいつ使用するのですか?達成しようとしていることに依存しますが、2つFilesがディスク上の同じファイルを指しているかどうかを確認しようとしている場合は、それらの正規パスを比較できます。ほんの一例。


7
Javaが「絶対」パスの実装を間違ったものにしたのは間違いありません。絶対パスの相対パス要素はすべて削除する必要があります。正規形式は、パス内のFSリンクまたはジャンクションをすべて削除します。
Lawrence Dol

but if you were trying to see if two Files are pointing at the same file on diskどうやって?例してください?
Asif Mushtaq

@UnKnown:正規のパスを使用します。
ローレンスドル2018年

67

要するに:

  • getPath()Fileオブジェクトの構築に使用されたパス文字列を取得します。これは現在の相対ディレクトリである場合があります。
  • getAbsolutePath() 相対パスの場合、現在のディレクトリに対して解決した後、パス文字列を取得し、完全修飾パスを生成します。
  • getCanonicalPath()は、現在のディレクトリに対する相対パスを解決した後、パス文字列を取得し、相対パス(.および..)を削除します。ファイルシステムリンクは、ファイルシステムが参照するファイルシステムオブジェクトを参照するための標準的な手段と見なされるパスを返します。

また、これらのそれぞれには、対応するFileオブジェクトを返す同等のファイルがあります。


36

getPath()Fileオブジェクトの作成に使用されたパスを返します。この戻り値は、実行された場所に基づいて変更されません(以下の結果はウィンドウの場合で、セパレーターは他の場所と明らかに異なります)

File f1 = new File("/some/path");
String path = f1.getPath(); // will return "\some\path"

File dir = new File("/basedir");
File f2 = new File(dir, "/some/path");
path = f2.getPath(); // will return "\basedir\some\path"

File f3 = new File("./some/path");
path = f3.getPath(); // will return ".\some\path"

getAbsolutePath()実行場所またはドライブに基づいてパスを解決します。だからから実行する場合c:\test

path = f1.getAbsolutePath(); // will return "c:\some\path"
path = f2.getAbsolutePath(); // will return "c:\basedir\some\path"
path = f3.getAbsolutePath(); // will return "c:\test\.\basedir\some\path"

getCanonicalPath()システムに依存します。パスが表す一意の場所を解決します。したがって、パスに「。」がある場合、それらは通常削除されます。

それらをいつ使用するかについて。それはあなたが達成しようとしていることに依存します。getPath()移植性に役立ちます。getAbsolutePath()ファイルシステムの場所を見つけるのにgetCanonicalPath()役立ち、2つのファイルが同じかどうかを確認するのに特に役立ちます。


この例を教えてもらえますか?getCanonicalPath() is particularly useful to check if two files are the same.
Asif Mushtaq

20

周りにあなたの頭を取得するには大きなものがあることをFile、クラスの試行がコール「階層パス名」(基本的には同様のパスに好きなもの日のビュー表すためc:/foo.txt/usr/muggins)を。これが、パスの観点からファイルを作成する理由です。説明している操作は、この「パス名」に対するすべての操作です。

  • getPath()../foo.txt)でファイルが作成されたパスを取得します
  • getAbsolutePath()ファイルの作成に使用されたパスをフェッチしますが、パスが相対(/usr/bobstuff/../foo.txt)の場合は現在のディレクトリに関する情報を含みます
  • getCanonicalPath() ファイルへの絶対パスの一意の表現をフェッチしようとします。これにより、「..」と「。」からの間接参照が排除されます。参照(/usr/foo.txt)。

注意:私は試みを言っています-正規パスを形成する際に、VMはをスローできますIOException。これは通常、一部のファイルシステム操作を実行しているために発生します。


3

使用する必要はほとんどありませんgetCanonicalPath()が、WindowsでDOS 8.3形式のファイル名のファイル(java.io.tmpdirSystemプロパティが返されるなど)を指定すると、このメソッドは「完全な」ファイル名を返します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.