File Paths in Kotlin

Here’s the translation of the Go code example to Kotlin, with explanations in Markdown format suitable for Hugo:

In Kotlin, we can use the java.io.File class and various utility functions to work with file paths. Here’s an example demonstrating file path operations:

import java.io.File

fun main() {
    // `File.separator` should be used to construct paths in a
    // portable way. We can use it with the `buildString` function
    // to create a path.
    val p = buildString {
        append("dir1")
        append(File.separator)
        append("dir2")
        append(File.separator)
        append("filename")
    }
    println("p: $p")

    // You should always use `File.separator` instead of
    // concatenating `/`s or `\`s manually. In addition
    // to providing portability, it will also
    // normalize paths.
    println(File("dir1", "filename").path)
    println(File("dir1${File.separator}..${File.separator}dir1", "filename").canonicalPath)

    // `parentFile` and `name` can be used to split a path to the
    // directory and the file.
    val file = File(p)
    println("Dir(p): ${file.parentFile}")
    println("Base(p): ${file.name}")

    // We can check whether a path is absolute.
    println(File("dir/file").isAbsolute)
    println(File("/dir/file").isAbsolute)

    val filename = "config.json"

    // Some file names have extensions following a dot. We
    // can split the extension out of such names.
    val ext = filename.substringAfterLast('.', "")
    println(ext)

    // To find the file's name with the extension removed,
    // use `substringBeforeLast`.
    println(filename.substringBeforeLast('.'))

    // `relativeTo` finds a relative path between a base and a
    // target. It throws an exception if the target cannot
    // be made relative to base.
    try {
        val rel = File("a/b/t/file").relativeTo(File("a/b"))
        println(rel)
    } catch (e: IllegalArgumentException) {
        println("Error: ${e.message}")
    }

    try {
        val rel = File("a/c/t/file").relativeTo(File("a/b"))
        println(rel)
    } catch (e: IllegalArgumentException) {
        println("Error: ${e.message}")
    }
}

To run the program, save it as FilePaths.kt and use kotlinc to compile and kotlin to run:

$ kotlinc FilePaths.kt -include-runtime -d FilePaths.jar
$ kotlin FilePaths.jar
p: dir1/dir2/filename
dir1/filename
dir1/filename
Dir(p): dir1/dir2
Base(p): filename
false
true
json
config
t/file
Error: Path is not relative: a/c/t/file

This Kotlin code demonstrates various file path operations using the java.io.File class. It shows how to construct paths, split paths into components, check for absolute paths, work with file extensions, and find relative paths. The File.separator is used to ensure portability across different operating systems.

Note that Kotlin, being a JVM language, leverages Java’s file handling capabilities. The java.io.File class provides most of the functionality we need, although some operations (like joining paths) are done manually using string operations.