Categories: Java

【Java入門】NIO.2 Pathインターフェース

この記事では、java.nio.file.Pathインターフェース(NIO.2)の使い方を紹介していきます。

Pathオブジェクトの取得方法

Pathオブジェクトは、ファイルシステムに関連付けられているため、Pathオブジェクトを取得するには、FileSystemオブジェクトを取得してからgetPathメソッドを使用する必要があります。(方法①)
あるいは、java.nio.file.Pathsgetメソッドを用いることもできます。(方法②)

Java

//方法①
FileSystem fs = FileSystems.getDefault();
Path p1 = fs.getPath("path");

Java

//方法②
Path p2 = Paths.get("path");

FileオブジェクトからPathオブジェクトを取得する方法

JavaSE7以降では、従来のFileクラスの代わりにPathインターフェースを使用することが推奨されています。
従来のFileオブジェクトからPathオブジェクトを取得するために、File#toPathメソッドが提供されている。

Java

File file = new File("C:\\workspace\\sample\\ex.txt");
Path path = file.toPath();

Pathインターフェースの主なメソッド

ここでは、Pathインターフェースの主なメソッドの使い方を紹介します。

メソッド 説明
getRoot そのパスのルートを返す。実行結果にはパス区切り記号も含まれる。
getParent フルパスで親ディレクトリを返す。
getName(int index) 引数にパスインデックスを表すint値を取り、そのインデックスに相当する階層のパスを返す。インデックス値はルートに最も近い階層が0となり、階層が深くなるにつれて1ずつ大きくなる。
getFileName パス階層における最下層のパス名を返します。ファイルだけでなく、ディレクトリも対象となる。また、パスがルートだけの場合は、このメソッドはNULLを返す。
getNameCount パス階層全体を構成するパス名の数をint値として返します。この結果にはルートは含まれない点に注意してください。なお、パスがルートだけの場合は、このメソッドは0を返します。
C://x//y//zの場合は、 cが0xが1yが2zが3を返す。
subPath パスの一部を抜き出すために使用することが出来、第一引数beginIndexに指定されたパスインデックスから第二引数に指定されたパスインデックスまでのパスを返します。
パスインデックスはルートに最も近い階層が0となり、階層が深くなるにつれて1ずつ大きくなります。「C:\x\y\z」の場合、xが0、yが1、zが2となります。 従ってsubPath(1,2)は、yディレクトリからzディレクトリまでのパスを返すことになります。但し、endIndexに指定されたパスインデックスは結果には含まれません。
resolve 引数に渡されたパスによって次のパスを返す。相対パスの場合(2つのパスを結合したパスを返す)。絶対パスの場合(渡されたパスそのものを返す)。空の場合(自分自身を表すパスを返します)
resolveSibling 引数に渡されたパスによって次のパスを返す。相対パスの場合(現在のパスの親ディレクトリからのパスとして解決したパスを返す。)。絶対パスの場合(渡されたパスそのものを返す。)但し、呼び出し側のパスが相対パスの場合は、引数で渡されたパスそのものを返す。
normalize 現在のパスに含まれる冗長なパス表現を正規化したパスを返す。カレントディレクトリを表す「.」や親ディレクトリを表す「..」のような特殊パスを解決したパスを返します。
relativize 渡されたパスを現在のパスからの相対パスとして解決したパスを返す。解決できないパスが渡された場合はjava.lang.illegalArgumentExceptionがスローされる。

getRootのサンプルコード

PathオブジェクトのルートをPath型で返します。

Java

Path p1 = Paths.get("C:\\workspace\\sample\\ex2.txt");
Path root = p1.getRoot();
System.out.println(root);

実行結果

C:\

getParentのサンプルコード

親ディレクトリをフルパスで返します。

Java

Path p1 = Paths.get("C:\\workspace\\sample\\ex2.txt");
Path oya = p1.getParent();
System.out.println(oya);

実行結果

C:\workspace\sample

getNameのサンプルコード

Java

Path p1 = Paths.get("C:\\workspace\\sample\\ex2.txt");
Path name0 = p1.getName(0);
Path name1 = p1.getName(1);
Path name2 = p1.getName(2);
System.out.println(name0);
System.out.println(name1);
System.out.println(name2);

実行結果

workspace
sample
ex2.txt

存在しないIndex値の場合はjava.lang.IllegalArgumentExceptionがスローされます。

Java

Path p1 = Paths.get("C:\\workspace\\sample\\ex2.txt");
Path name3 = p1.getName(3);
System.out.println(name3);

実行結果

Exception in thread "main" java.lang.IllegalArgumentException
at sun.nio.fs.WindowsPath.getName(WindowsPath.java:620)
at sun.nio.fs.WindowsPath.getName(WindowsPath.java:44)
at test.main(test.java:10)

getFileNameのサンプルコード

Pathオブジェクトのパス階層における最下層のパス名を返します。
getName(MaxIndex)とかやらなくてもこのメソッドで取得することができます。
最下層がフォルダの場合も取得することができます。
但し、パスがルートだけの場合は、このメソッドはNULLを返します。

最下層がファイルの場合のサンプルコード

Java

Path p1 = Paths.get("C:\\workspace\\sample\\ex2.txt");
Path name = p1.getFileName();
System.out.println(name);

実行結果

ex2.txt

最下層がフォルダの場合のサンプルコード

Java

Path p1 = Paths.get("C:\\workspace\\sample\\");
Path name = p1.getFileName();
System.out.println(name);

実行結果

eample

パスがルートのみのサンプルコード

Java

Path p1 = Paths.get("C:\\");
Path name = p1.getFileName();
System.out.println(name);

実行結果

null

getNameCountのサンプルコード

パス階層の数をint値で返します。ルートパスのみの場合は0が返ります。
絶対パスの場合、以下のようになります。

Java

Path p1 = Paths.get("C:\\workspace\\sample\\ex2.txt");
int cnt = p1.getNameCount();
System.out.println(cnt);

実行結果

3

相対パスの場合、以下のようになります。

Java

Path p1 = Paths.get("\\sample\\ex2.txt");
int cnt = p1.getNameCount();
System.out.println(cnt);

実行結果

2

ルートだけの場合、以下のようになります。

Java

Path p1 = Paths.get("C:\\");
int cnt = p1.getNameCount();
System.out.println(cnt);

実行結果

0

subPathのサンプルコード

subPathメソッドは、第一引数から第二引数にあるパスを抜き出します。但し、第二引数で指定したIndex値のパスは抜き出されません。
Index値は、ルートに近い順から0になるので、それぞれworkspaceが0,sampleが1,ex2.txtが2となります。

Java

Path p1 = Paths.get("C:\\workspace\\sample\\ex2.txt");
Path extractPath = p1.subpath(0,3);
System.out.println(extractPath);

実行結果

workspace\sample\ex2.txt

無効なパスインデックスを指定した場合はjava.lang.IllegalArgumentExceptionがスローされます。

Java

Path p1 = Paths.get("C:\\workspace\\sample\\ex2.txt");
Path extractPath = p1.subpath(0,4);
System.out.println(extractPath);

実行結果

Exception in thread "main" java.lang.IllegalArgumentException
at sun.nio.fs.WindowsPath.subpath(WindowsPath.java:632)
at sun.nio.fs.WindowsPath.subpath(WindowsPath.java:44)
at test.main(test.java:10)

resolveのサンプルコード

引数に渡されたパスが相対パスの場合

Java

Path p1 = Paths.get("C:\\workspace\\sample\\ex2.txt");
Path p2 = Paths.get("sample2\\ex99.txt");
Path result = p1.resolve(p2);System.out.println(result);

実行結果

C:\workspace\sample\ex2.txt\sample2\ex99.txt

引数に渡されたパスが相対パスの場合、第一引数と第二引数のパスを結合したパスを返します。

引数に渡されたパスが絶対パスの場合

Java

Path p1 = Paths.get("C:\\workspace\\sample\\ex2.txt");
Path p2 = Paths.get("C:\\workspace\\sample\\ex99.txt");
Path result = p1.resolve(p2);System.out.println(result);

実行結果

C:\workspace\sample\ex99.txt

引数に渡されたパスが絶対パスの場合、第二引数のパスを返します。

引数に渡されたパスが空の場合

Java

Path p1 = Paths.get("C:\\workspace\\sample\\ex2.txt");
Path p2 = Paths.get("");
Path result = p1.resolve(p2);System.out.println(result);

実行結果

C:\workspace\sample\ex2.txt

引数に渡されたパスが空の場合、第一引数のパスを返します。
但し、引数に渡されたパスが空でなくNULLの場合は、java.lang.NullPointerExceptionがスローされます。

Java

Path p1 = Paths.get("C:\\workspace\\sample\\ex2.txt");
Path p2 = Paths.get(null);
Path result = p1.resolve(p2);System.out.println(result);

実行結果

Exception in thread "main" java.lang.NullPointerException
at java.nio.file.Paths.get(Paths.java:132)
at test.main(test.java:10)

resolveを連結した場合

Java

Path p1 = Paths.get("C:\\abc");
Path p2 = Paths.get("D:\\xyz");
Path p3 = Paths.get("abc");System.out.println(p1.resolve(p2).resolve(p3))//D:\\xyz\\abc

p1.resolve(p2).resolve(p3)の処理は、p1.resolve(p2)(p2).resolve(p3)に分けて考えます。
p1.resolve(p2)は、p2が絶対パスとして渡されているので、"D:\\xyz"が返ります。
(p2).resolve(p3)は、p3が相対パスとして渡されているので、"D:\\xyz""abc"が連結されてD:\\xyz\\abcの結果になります。

resolveSiblingのサンプルコード

引数に渡されたパスが絶対パスの場合、以下のようになります。

Java

Path p1 = Paths.get("C:\\workspace\\sample\\ex2.txt");
Path p2 = Paths.get("C:\\workspace\\sample\\ex99.txt");
Path result = p1.resolveSibling(p2);System.out.println(result);

実行結果

C:\workspace\sample\ex99.txt

引数に渡されたパスが相対パスの場合、以下のようになります。
現在のパスの親ディレクトリを起点としてパスを解決します。

Java

Path p1 = Paths.get("C:\\workspace\\sample\\ex2.txt");
Path p2 = Paths.get("sample2\\ex99.txt");
Path result = p1.resolveSibling(p2);System.out.println(result);

実行結果

C:\workspace\sample\sample2\ex99.txt

normalizeのサンプルコード

「..」や「.」を取り除き、冗長なパスを正規化したパスにして返します。

Java

Path p1 = Paths.get("C:\\workspace\\sample\\..\\..\\ex2.txt");
Path result = p1.normalize();System.out.println(result);

実行結果

C:\ex2.txt

relativizeのサンプルコード

引数に渡されたパスを現在パスからの相対パスとして解決したパスを返します。

Java

Path p1 = Paths.get("C:\\workspace\\sample\\ex2.txt");
Path p2 = Paths.get("C:\\workspace2\\sample99\\ex2.txt");
Path result = p1.relativize(p2);System.out.println(result);

実行結果

..\..\..\workspace2\sample99\ex2.txt

現在パスの「ex2.txt」から「workspace2」へ辿るには3階層上へ移動して「c:\」まで戻る必要があるため、「..\..\..\」となります。
また、解決できないパスの場合は、java.lang.IllegalArgumentExceptionがスローされます。

Java

Path p1 = Paths.get("C:\\workspace\\sample\\ex2.txt");
Path p2 = Paths.get("workspace2\\sample99\\ex2.txt");
Path result = p1.relativize(p2);System.out.println(result);

実行結果

Exception in thread "main" java.lang.IllegalArgumentException: 'other' is different type of Path
at sun.nio.fs.WindowsPath.relativize(WindowsPath.java:388)
at sun.nio.fs.WindowsPath.relativize(WindowsPath.java:44)
at test.main(test.java:11)

以上で記事の解説はお終い!

もっとJavaやSpringを勉強したい方にはUdemyがオススメ!同僚に差をつけよう!

issiki_wp