diff --git a/libraries/stdlib/src/kotlin/io/files/FilePathComponents.kt b/libraries/stdlib/src/kotlin/io/files/FilePathComponents.kt index 4d72925be48..8f2d9e5189b 100644 --- a/libraries/stdlib/src/kotlin/io/files/FilePathComponents.kt +++ b/libraries/stdlib/src/kotlin/io/files/FilePathComponents.kt @@ -91,6 +91,11 @@ public data class FilePathComponents(public val rootName: String, public val fil */ public fun size(): Int = fileList.size + /** + * [File] representing root of the path (for example, `/` or `C:` or empty for relative paths). + */ + public val root: File = File(rootName) + /** * Returns a sub-path of the path, starting with the directory at the specified [beginIndex] and up * to the specified [endIndex]. diff --git a/libraries/stdlib/src/kotlin/io/files/Utils.kt b/libraries/stdlib/src/kotlin/io/files/Utils.kt index 7f757f9459c..255c0a0ff64 100644 --- a/libraries/stdlib/src/kotlin/io/files/Utils.kt +++ b/libraries/stdlib/src/kotlin/io/files/Utils.kt @@ -131,7 +131,7 @@ private fun File.relativeToOrNull(base: File): String? { // Check roots val thisComponents = this.filePathComponents().normalize() val baseComponents = base.filePathComponents().normalize() - if (thisComponents.rootName != baseComponents.rootName) { + if (thisComponents.root != baseComponents.root) { return null } @@ -333,7 +333,7 @@ public fun File.listFiles(filter: (file: File) -> Boolean): Array? = listF public fun File.startsWith(other: File): Boolean { val components = filePathComponents() val otherComponents = other.filePathComponents() - if (components.rootName != otherComponents.rootName && otherComponents.rootName != "") + if (components.root != otherComponents.root && otherComponents.rootName != "") return false return if (components.size() < otherComponents.size()) false else components.fileList.subList(0, otherComponents.size()).equals(otherComponents.fileList) @@ -360,7 +360,7 @@ public fun File.startsWith(other: String): Boolean = startsWith(File(other)) public fun File.endsWith(other: File): Boolean { val components = filePathComponents() val otherComponents = other.filePathComponents() - if (components.rootName != otherComponents.rootName && otherComponents.rootName != "") + if (components.root != otherComponents.root && otherComponents.rootName != "") return false val shift = components.size() - otherComponents.size() return if (shift < 0) false @@ -436,8 +436,7 @@ public fun File.resolve(relative: String): File = resolve(File(relative)) public fun File.resolveSibling(relative: File): File { val components = filePathComponents() val parentSubPath = if (components.size() == 0) File("..") else components.subPath(0, components.size() - 1) - val rootName = components.rootName - return File(rootName).resolve(parentSubPath).resolve(relative) + return components.root.resolve(parentSubPath).resolve(relative) } /** diff --git a/libraries/stdlib/test/io/Files.kt b/libraries/stdlib/test/io/Files.kt index 586ddc3b1e6..93a27bf5cd5 100644 --- a/libraries/stdlib/test/io/Files.kt +++ b/libraries/stdlib/test/io/Files.kt @@ -7,6 +7,8 @@ import kotlin.test.* class FilesTest { + private val isCaseInsensitiveFileSystem = File("C:/") == File("c:/") + @test fun testPath() { val fileSuf = System.currentTimeMillis().toString() val file1 = createTempFile("temp", fileSuf) @@ -100,6 +102,10 @@ class FilesTest { assertEquals("..", file6.relativeTo(file7)) assertEquals("Documents", file7.relativeTo(file6)) + if (isCaseInsensitiveFileSystem) { + assertEquals("bar", File("C:/bar").relativeTo(File("c:/"))) + } + val file8 = File("""\\my.host\home/user/documents/vip""") val file9 = File("""\\my.host\home/other/images/nice""") @@ -215,6 +221,9 @@ class FilesTest { assertTrue(File("C:\\Users\\Me\\Temp\\Game").startsWith("C:\\Users\\Me")) assertFalse(File("C:\\Users\\Me\\Temp\\Game").startsWith("C:\\Users\\He")) assertTrue(File("C:\\Users\\Me").startsWith("C:\\")) + if (isCaseInsensitiveFileSystem) { + assertTrue(File("C:\\Users\\Me").startsWith("c:\\")) + } } @test fun endsWith() { @@ -224,6 +233,9 @@ class FilesTest { assertTrue(File("/foo/bar/gav/bar").endsWith("/gav/bar")) assertFalse(File("/foo/bar/gav").endsWith("/bar")) assertFalse(File("foo/bar").endsWith("/bar")) + if (isCaseInsensitiveFileSystem) { + assertTrue(File("/foo/bar").endsWith("Bar")) + } } @test fun subPath() {