1.そもそもパスとURIってなんだっけ
パス…ファイルシステムのリソースの在処を示す。 標準のDOSパスの場合、パスは3つの部分から構成される。
- ボリュームまたはドライブ文字とそれに続くボリューム区切り記号 (:)。
=>Cドライブ直下の場合はパスの先頭の"C:"
- ディレクトリ名。ディレクトリ区切り文字によって、入れ子になっているディレクトリ階層内でサブディレクトリが分割されます。
=>ディレクトリ区切り文字はWindowsの場合はバックスラッシュ(\)。
- 任意のファイル名。
=>readme.txtとか。
https://learn.microsoft.com/ja-jp/dotnet/standard/io/file-path-formats
URI…
- スキーム
=>http:、ftp:、data:、file:など通信手段を示す
authority =>スキームのあと"//"で始まる部分。ユーザ情報、ホスト、ポートから構成される。 ホストは"www.google.com"、ポートはポート番号。
- パス
=>指定したauthority内のリソースの在処を表す。 上で説明したパスに同じ。
- クエリ 指定したauthority内のリソースの在処を表す。 上で説明したパスに同じ。
- フラグメント ??
2.PathsクラスとURIクラスを利用する
JavaのURIクラスには、上で説明したスキームやクエリを取得するメソッドのほか、URIオブジェクトを生成するcreateメソッドが用意されています。
public static URI create(String str)
パラメータには、URIとして分析可能な文字列を渡します。
2.1. エラーになる表現もある
String pattern = "パスは{0}.\nURIは{1}";
URI uri2 = URI.create("file:/pleiades/workspace/JavaStudy/text/sample/test2.txt");
Path path2 = Paths.get(uri2);
System.out.println(MessageFormat.format(pattern,path2.toString() ,uri2.toString()));
URI uri3 = URI.create("C:/pleiades/workspace/JavaStudy/text/sample/test2.txt");
Path path3 = Paths.get(uri3);
System.out.println(MessageFormat.format(pattern,path3.toString(), uri3.toString()));
URI uri4 = URI.create("./text/test/txt");
Path path4 = Paths.get(uri4);
System.out.println(MessageFormat.format(pattern, uri4.toString(), path4.toString()));
URI uri5 = URI.create("file:\\pleiades\\workspace\\JavaStudy\\text\\sample\\test2.txt");
Path path5 = Paths.get(uri5);
System.out.println(MessageFormat.format(pattern, path5.toString(), uri5.toString()));
URIクラスのcreateメソッド※を利用して、URIクラスのオブジェクトを作成し、さらに、URIクラスのオブジェクトを利用してPathsクラスのgetメソッドからPathを指定します。
最後に、MessageFormatクラスのformatメソッド※でURIクラスオブジェクトとPathクラスオブジェクトの文字列表現を出力。
適当に4つ並べてみなしたが、この中で正しくPathクラスオブジェクトを取得できるのは1つだけです。
※MessageFormat.formatメソッド…第一引数のpatternに変数を埋め込む書式パターン、第二引数以降に埋め込む変数を指定して、メッセージの指定部分のみを変更する。
2.2. 解答編
//パスは\pleiades\workspace\JavaStudy\text\sample\test2.txt.
//URIはfile:///pleiades/workspace/JavaStudy/text/sample/test2.txt
URI uri2 = URI.create("file:/pleiades/workspace/JavaStudy/text/sample/test2.txt");
Path path2 = Paths.get(uri2);
//FileSystemNotFoundException:Privider"C"not installed
URI uri3 = URI.create("C:/pleiades/workspace/JavaStudy/text/sample/test2.txt");
Path path3 = Paths.get(uri3);
//IllegalArgumentException:missing scheme
URI uri4 = URI.create("./text/test/txt");
Path path4 = Paths.get(uri4);
//IllegalArgumentException:Illegal character in opaque part at index 5
URI uri5 = URI.create("file:\\pleiades\\workspace\\JavaStudy\\text\\sample\\test2.txt");
Path path5 = Paths.get(uri5);
【失敗例1】
//FileSystemNotFoundException:Privider"C"not installed
URI uri3 = URI.create("C:/pleiades/workspace/JavaStudy/text/sample/test2.txt");
Path path3 = Paths.get(uri3);
ドライブの"C"をスキームとして分析してしまうためエラー。
【失敗例2】
//IllegalArgumentException:missing scheme
URI uri4 = URI.create("./text/test/txt");
Path path4 = Paths.get(uri4);
スキーム(https:など)を指定しない相対パスで生成したURIクラスオブジェクトを引数にしてgetを呼び出すとillegalArgumentExceptionがスローされます。
なお、
Path path4 = Paths.get("./text/test/txt");
のように、URIクラスオブジェクトを利用せず、Pathsクラスのgetメソッドに相対パスを文字列で指定した場合は、正しくリソースのパスを指定することができます。
相対パスで指定した場合、ルートはプロジェクトのフォルダになります(上掲の例だとJavaStudy)。
【失敗例3】
URI uri5 = URI.create("file:\\pleiades\\workspace\\JavaStudy\\text\\sample\\test2.txt");
Path path5 = Paths.get(uri5);
windowsのディレクトリ区切り文字であるバックスラッシュ(/)を利用しているパターン。
"Illegal character in opaque part at index 5"
=>"opaque"はURIのデータ格納部分。バックスラッシュで区切りを表現してはいけない。
【成功例】
//パスは\pleiades\workspace\JavaStudy\text\sample\test2.txt.
//URIはfile:/pleiades/workspace/JavaStudy/text/sample/test2.txt
URI uri2 = URI.create("file:/pleiades/workspace/JavaStudy/text/sample/test2.txt");
Path path2 = Paths.get(uri2);
パスはwindowsの区切り文字であるバックスラッシュで表現されていることがわかります。また、URIのスキーム部はパスとしては表現されないこともわかります。
なお、Ubuntuで実行した場合、
//パスは/pleiades/workspace/JavaStudy/text/sample/test2.txt.
//URIはfile:/pleiades/workspace/JavaStudy/text/sample/test2.txt
パスの区切り文字はスラッシュとなります。