fileスキームのURLを、ローカルファイルを参照可能なパスに変換しようとしたところ、単純な文字列操作以外の方法でこれを取り扱うのが、思ったよりも手こずったのでメモ。手こずったとはいえ、方法を知っていれば難しくはないのですが、知らなかったなあということで。

環境要件

  • Oracle Java 1.8.0_161
  • Kotlin 1.2.71
  • Apache Maven 3.6.0
$ ./mvnw -version
Apache Maven 3.6.0 (97c98ec64a1fdfee7767ce5ffb20918da4f719f3; 2018-10-25T03:41:47+09:00)
Maven home: ~/.m2/wrapper/dists/apache-maven-3.6.0-bin/2dakv70gp803gtm5ve1ufmvttn/apache-maven-3.6.0
Java version: 1.8.0_161, vendor: Oracle Corporation, runtime: /Library/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home/jre
Default locale: ja_JP, platform encoding: UTF-8
OS name: "mac os x", version: "10.13.6", arch: "x86_64", family: "mac"

fileスキームの変換

URL(it).toURI().schemeSpecificPartを使うことで、URLから適切にスキームパートを取り除けた。いくつかのURLパターンごとの実行サンプルは以下の通り。

import java.net.URL
import java.nio.file.Paths

fun main(args: Array<String>) {
    listOf(
        "file:abc/def",
        "file:/abc/def",
        "file:./abc/def",
        "file:../abc/def",
        "file://abc/def",
        "file:///abc/def",
        "file://./abc/def",
        "file://../abc/def"
    ).forEach {
        val path = Paths.get(URL(it).toURI().schemeSpecificPart)
        println("${it.padEnd(17)} -> $path")
    }
}

// file:abc/def      -> abc/def
// file:/abc/def     -> /abc/def
// file:./abc/def    -> ./abc/def
// file:../abc/def   -> ../abc/def
// file://abc/def    -> /abc/def
// file:///abc/def   -> /abc/def
// file://./abc/def  -> /./abc/def
// file://../abc/def -> /../abc/def

参考