1. 概要

java.io.File クラスには、 getPath() getAbsolutePath() getCanonicalPath()の3つのメソッドがあります。ファイルシステムパス。

この記事では、それらの違いを簡単に見て、一方を他方よりも使用することを選択できるユースケースについて説明します。

2. メソッドの定義と例

ユーザーのホームディレクトリに次のディレクトリ構造が存在することに基づく例とともに、3つのメソッドの定義を確認することから始めましょう。

|-- baeldung
    |-- baeldung.txt
    |-- foo
    |   |-- foo-one.txt
    |   \-- foo-two.txt
    \-- bar
        |-- bar-one.txt
        |-- bar-two.txt
        \-- baz
            |-- baz-one.txt
            \-- baz-two.txt

2.1. getPath()

簡単に言うと、 getPath()は、ファイルの抽象パス名のString表現を返します。 これは基本的にファイルコンストラクターに渡されるパス名です。

したがって、 File オブジェクトが相対パスを使用して作成された場合、 getPath()メソッドからの戻り値も相対パスになります。

{user.home} / baeldungディレクトリから次のコードを呼び出す場合:

File file = new File("foo/foo-one.txt");
String path = file.getPath();

path変数の値は次のとおりです。

foo/foo-one.txt  // on Unix systems
foo\foo-one.txt  // on Windows systems

Windowsシステムでは、名前区切り文字が、コンストラクターに渡されたスラッシュ(/)文字からバックスラッシュ(\)文字に変更されていることに注意してください。 これは、返される文字列が常にプラットフォームのデフォルトの名前区切り文字を使用するためです。

2.2. getAbsolutePath()

getAbsolutePath()メソッドは、現在のユーザーディレクトリのパスを解決した後、ファイルのパス名を返します。これは絶対パス名と呼ばれます。 したがって、前の例では、 file.getAbsolutePath()は次を返します。

/home/username/baeldung/foo/foo-one.txt     // on Unix systems
C:\Users\username\baeldung\foo\foo-one.txt  // on Windows systems

このメソッドは、相対パスの現在のディレクトリのみを解決します。 省略表現(「。」や「 ..」など)は、これ以上解決されません。 したがって、ディレクトリ {user.home} / baeldungから次のコードを実行すると:

File file = new File("bar/baz/../bar-one.txt");
String path = file.getAbsolutePath();

変数pathの値は次のようになります。

/home/username/baeldung/bar/baz/../bar-one.txt      // on Unix systems
C:\Users\username\baeldung\bar\baz\..\bar-one.txt   // on Windows systems

2.3. getCanonicalPath()

getCanonicalPath()メソッドはさらに一歩進んで、は絶対パス名と、「。」のような省略形または冗長な名前を解決します。 および「..」ディレクトリ構造に従って。 また、Unixシステムではシンボリックリンクを解決し、Windowsシステムではドライブ文字を標準のケースに変換します。

したがって、前の例では、 getCanonicalPath()メソッドは次を返します。

/home/username/baeldung/bar/bar-one.txt     // on Unix systems
C:\Users\username\baeldung\bar\bar-one.txt  // on Windows systems

別の例を見てみましょう。 現在のディレクトリを${user.home}/baeldungとして指定します。Fileオブジェクトは、パラメータ new File(“ bar / baz /./ baz-one.txt”を使用して作成されます。 ) getCanonicalPath()の出力は次のようになります。

/home/username/baeldung/bar/baz/baz-one.txt     // on Unix systems
C:\Users\username\baeldung\bar\baz\baz-one.txt  // on Windows Systems

省略表現を使用する方法は無限にあるため、ファイルシステム上の単一のファイルが無限の数の絶対パスを持つ可能性があることに言及する価値があります。 ただし、正規パスは、そのような表現がすべて解決されるため、常に一意になります

最後の2つのメソッドとは異なり、 getCanonicalPath()は、ファイルシステムクエリを必要とするため、IOExceptionをスローする場合があります。

たとえば、Windowsシステムでは、不正な文字の1つを使用して File オブジェクトを作成すると、正規パスを解決するとIOExceptionがスローされます。

new File("*").getCanonicalPath();

3. 使用事例

File オブジェクトをパラメーターとして受け取り、その完全修飾名をデータベースに保存するメソッドを作成しているとしましょう。 パスが相対的なものなのか、速記が含まれているのかはわかりません。 この場合、 getCanonicalPath()を使用することをお勧めします。

ただし、 getCanonicalPath()はファイルシステムを読み取るため、パフォーマンスが低下します。 冗長な名前やシンボリックリンクがなく、ドライブ文字の大文字と小文字が標準化されている場合(Windows OSを使用している場合)、 getAbsoultePath()を使用することをお勧めします。

4. 結論

このクイックチュートリアルでは、ファイルシステムパスを取得するための3つのFileメソッドの違いについて説明しました。 また、一方の方法がもう一方の方法よりも優先される可能性があるユースケースも示しました。

この記事の例を示すJunitテストクラスは、GitHubにあります。