2009-07-08 4 views
499

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

いつそれぞれを使用しますか?要するに

+29

私はこれで何度もjavaドキュメントをチェックしました... + 1 – Liam

+0

パス(path)とパス(path)との間の良い中間地である 'Path.toAbsolutePath()。normalize()'は忘れてはいけません。絶対パスだけ。 – eckes

答えて

551

は、これらのファイル名を考慮してください

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

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

C:\temp\myapp\bin\..\\..\file.txt - これはパスと絶対パスです。標準的な方法ではありません。

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

パスから正規のパスに変換すると絶対パスになります(通常は現在の作業ディレクトリをタックします(例:./file.txtc:/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 
+8

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

+1

パスは実際にはそれらの問題やコンポーネントの存在を考慮しておらず、その構文のみを考慮しています。 –

+0

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

59

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

また、それぞれに相当するFileがあり、対応するFileオブジェクトを返します。

105

私が見つけた最良の方法このようなことを感じるには、それらを試してみてください:

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台のディスクがディスク上の同じファイルを指しているかどうかを確認しようとしていた場合は、正規パスを比較することができます。ほんの一例。

+6

Javaは絶対パスの実装が間違っていると言えるでしょう。実際に絶対パス内の相対パス要素を削除しておく必要があります。正準形式では、パス内のFSリンクまたはジャンクションが削除されます。 –

+0

'しかし、2つのファイルがディスク上の同じファイルを指しているかどうかを確認しようとしていたらどうすればいいですか?どうしますか? – UnKnown

18

の周りにあなたの頭を取得するための大きなものはFileクラスは、Sunは、「階層パス名」(c:/foo.txtまたは/usr/mugginsのような基本的にパス)を呼び出すために好きなもののビューを表現しようとしていることです。これが、パスの観点からファイルを作成する理由です。あなたが記述している操作は、この "パス名"に対するすべての操作です。

  • getPath()
  • getAbsolutePath()がファイルを用いて作成されたパスをフェッチするが、パスが相対的である場合、現在のディレクトリについての情報を含む(/usr/bobstuff/../foo.txt)(../foo.txt)ファイルを用いて作成されたパスをフェッチ
  • getCanonicalPath()の試行は、ファイルへの絶対パスのユニークな表現を取得します。これにより、 ".."と "。"の間接参照がなくなります。参考文献(/usr/foo.txt)。

私は試みを言う注意 - 正規のパスを形成することで、VMはIOExceptionを投げることができます。これは、通常、ファイルシステムの操作のいずれかが失敗する可能性があるために発生します。

31

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()が実行場所またはドライブに基づいてパスを解決します(Windowsのためのもので、以下の結果、セパレータは、他の場所で明らかに異なっています)。だから、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つのファイルが同じかどうかを確認するのに特に便利です。

+0

私にこれの例を教えていただけますか? 'getCanonicalPath()は、2つのファイルが同じかどうかを確認するのに特に便利です。 – UnKnown

3

getCanonicalPath()を使用する必要はほとんどありませんが、java.io.tmpdirシステムプロパティが返すような、WindowsのDOS 8.3形式のファイル名を指定すると、このメソッドは "フル"ファイル名を返します。

関連する問題