File Paths in Scala

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

The java.nio.file.Paths class provides functions to parse and construct file paths in a way that is portable between operating systems; dir/file on Linux vs. dir\file on Windows, for example.

import java.nio.file.{Path, Paths}
import java.io.File

object FilePaths {
  def main(args: Array[String]): Unit = {
    // Paths.get should be used to construct paths in a portable way.
    // It takes any number of arguments and constructs a hierarchical path from them.
    val p: Path = Paths.get("dir1", "dir2", "filename")
    println(s"p: $p")

    // You should always use Paths.get instead of concatenating
    // '/' or '\' manually. In addition to providing portability,
    // Paths.get will also normalize paths by removing superfluous
    // separators and directory changes.
    println(Paths.get("dir1//", "filename"))
    println(Paths.get("dir1/../dir1", "filename"))

    // getParent and getFileName can be used to split a path to the
    // directory and the file. There's no direct equivalent to Split in Scala.
    println(s"Dir(p): ${p.getParent}")
    println(s"Base(p): ${p.getFileName}")

    // We can check whether a path is absolute.
    println(Paths.get("dir/file").isAbsolute)
    println(Paths.get("/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.substring(filename.lastIndexOf('.'))
    println(ext)

    // To find the file's name with the extension removed,
    // use substring.
    println(filename.substring(0, filename.length - ext.length))

    // Paths.get.relativize finds a relative path between a base and a
    // target. It returns a relative path if possible.
    val base = Paths.get("a/b")
    val target1 = Paths.get("a/b/t/file")
    val target2 = Paths.get("a/c/t/file")
    
    println(base.relativize(target1))
    println(base.relativize(target2))
  }
}

To run the program, save it as FilePaths.scala and use scala:

$ scala FilePaths.scala
p: dir1\dir2\filename
dir1\filename
dir1\filename
Dir(p): dir1\dir2
Base(p): filename
false
true
.json
config
t\file
..\c\t\file

Note that the output may vary slightly depending on the operating system, especially for path separators.

In Scala, we use the java.nio.file.Paths class to handle file paths in a cross-platform manner. This class provides similar functionality to Go’s filepath package. The Paths.get method is used to construct paths, similar to filepath.Join in Go.

For operations like splitting paths and getting file extensions, we use methods on the Path object or string operations, as Scala doesn’t have direct equivalents for all of Go’s filepath functions.

The relativize method in Scala is similar to Go’s Rel function, providing relative paths between two locations.

Remember that while this code provides similar functionality to the Go example, there might be slight differences in behavior due to the underlying implementations in the JVM and Scala.