The Path interface is provided to Kotlin by the java.nio.file.Paths package. It represents Paths on the underlying file system and provides a number of useful utility methods for working with paths. Here is an example program followed by output and an explanation.
import java.io.BufferedWriter
import java.io.FileWriter
import java.nio.file.Paths
val belchers = "belchers.txt"
fun makeBelcherFile(){
val names = listOf("Bob", "Linda", "Tina", "Gene", "Louise")
BufferedWriter(FileWriter(belchers)).use { writer ->
names.forEach { name ->
with(writer){
write(name)
newLine()
}
}
}
}
fun main(args : Array<String>){
//Just make a file on the file system for demonstration purposes
makeBelcherFile()
//Get a reference to our example path on the disk.
//In this case, we are using Paths.get() to get a reference to the current working directory
//and then using the resolve() method to add the belchers.txt file to the path
val belcherPath = Paths.get(System.getProperty("user.dir")).resolve(belchers)
val template = "\t%-30s => %s"
with(belcherPath){
println("File Information")
//The fileName property returns the name of the file
println(template.format("File Name", fileName))
//The root property return the the root folder of the path
println(template.format("File Path Root", root))
//The parent property returns the parent folder of the file
println(template.format("File Path Parent", parent))
//The nameCount returns how many items are in the path
println(template.format("Name Count", nameCount))
//The subpath() method returns a portion of the path
println(template.format("Subpath (0, 1)", subpath(0, 1)))
//The normalize method returns items such as . or .. from the path
println(template.format("Normalizing", normalize()))
//True if this is an absolute path otherwise false
println(template.format("Is Absolute Path?", isAbsolute))
//Convert to an absolute path if needed
println(template.format("Absolute Path", toAbsolutePath()))
//Check if the path starts with a path. In this example, we are using the home folder
println(template.format("Starts with ${System.getProperty("user.home")}?", startsWith(System.getProperty("user.home"))))
println()
println("Elements of the Path")
//We can print each portion of the path individually also!
forEach { it -> println("\tPortion => $it") }
}
}
Here is the output when run on my machine.
File Information
File Name => belchers.txt
File Path Root => /
File Path Parent => /Users/stonesoup/IdeaProjects/OCJAP
Name Count => 5
Subpath (0, 1) => Users
Normalizing => /Users/stonesoup/IdeaProjects/OCJAP/belchers.txt
Is Absolute Path? => true
Absolute Path => /Users/stonesoup/IdeaProjects/OCJAP/belchers.txt
Starts with /Users/stonesoup? => true
Elements of the Path
Portion => Users
Portion => stonesoup
Portion => IdeaProjects
Portion => OCJAP
Portion => belchers.txt
Explanation
The program writes out a basic text file to the file system for demonstration purposes. We are going to focus on the main function. Our first task is to get a Path object that points to our belchers.txt file. We use the Paths.get() factory method and path in a path on the file system. In our example, we use the current working directory by using the System property “user.dir”.
We could have also added the belchers.txt to the end of the current working directory. However, I wanted to demonstrate the resolve method that combines two paths into a single path. So we chain the resolve method to the returned Path object and add belchers.txt. The returned Path object points to the path of belchers.txt on the file system.
The next part of the program demonstrates commonly used methods found on the Path interface. Line 33 prints the name of the file by using the fileName property. Next we print out the root of the path by using the root property (line 36). When we want to know the parent of a path, we can use the parent property (line 39).
The Path interface has a nameCount property (line 42) that returns the number of items in a path. So if a path is /Users/stonesoup/IdeaProjects/OCJAP/belchers.txt
, nameCount returns 5, one for each item between each slash (/) character. The nameCount is useful when working with the Subpath function (line 45), which accepts a start index (inclusive) and an end index (exclusive) and returns a Path object based on the indexes.
Sometimes paths are abnormal paths and may have “.” or “..” characters in the path. When we want to remove such characters, we use the normalize() function (line 48) which strips out abnormal characters from the path. Depending on the work we may be doing, we may want to test if the Path is a relative path or an abosulte path. The Path interface has an isAbsolute property (line 51) for such purposes. It returns true if the path is an absolute path otherwise false.
Should we wish to convert a relative path into an absolute path, we only need to call the toAbsolutePath() function (line 54) and we will get an absolute path. We can also check if a path starts with a certain path. In our example, line 57, we check if our path starts with the users home directory (user.home). It returns true or false based on the outcome.
Path supports the forEach() function. Line 62 shows an example of how we can iterate through each part of the Path. The it variable holds each portion of the path and the program prints each part of the path.
Common Methods
We spoke about each method as it relates the program above. Here are each of the commonly used methods broken down.
Paths.get(first : String, varages more : String) : Path
The get() converts a String (or URI in the overloaded version) into a Path object. When we use use the varags part, the Path will use the OS name seperator. So Unix paths will have a forward slash, while Windows ones will have a backslash.
val home = Paths.get(System.getProperty("user.home"))
parent : Path
The parent property returns a Path object that points to the parent of the current Path object.
val parent = home.parent
nameCount : Int
The nameCount returns the number of items in the path.
val count = home.nameCount
subPath(beginIndex : Int, endIndex : Int) : Path
The subPath method is used to return a portion of the path object. The beginIndex is inclusive while the endIndex is exclusive.
val part = home.subPath(0, 2)
normalize() : Path
The normalize() method returns a Path object without unneeded characters.
val norm = home.normalize()
resolve(other : Path) : Path, resolve(other : String): Path
Returns a Path object that is a combined path between the current path and the other parameter.
val belchers = home.resolve("belchers.txt")
isAbsolute : Boolean
True if the Path is an absolute path otherwise it’s false.
val absolute = home.isAbsolute
startsWith(path : String) : Boolean, startsWith(path : Path) : Boolean
True if the current path starts with the supplied path argument.
val hasRoot = home.startsWith("/")
toAbsolutePath() : Path
Returns a Path object that is the aboslute path of the current Path.
val abs = home.toAbsolutePath()
References
https://docs.oracle.com/javase/8/docs/api/java/nio/file/Path.html
Like this:
Like Loading...