How do I write to a file in Kotlin?

yiwei picture yiwei · Feb 16, 2016 · Viewed 46.1k times · Source

I can't seem to find this question yet, but what is the simplest, most-idiomatic way of opening/creating a file, writing to it, and then closing it? Looking at the kotlin.io reference and the Java documentation I managed to get this:

fun write() {
    val writer = PrintWriter("file.txt")  // java.io.PrintWriter

    for ((member, originalInput) in history) {  // history: Map<Member, String>
        writer.append("$member, $originalInput\n")
    }

    writer.close()
}

This works, but I was wondering if there was a "proper" Kotlin way of doing this?

Answer

Jayson Minard picture Jayson Minard · Feb 17, 2016

A bit more idiomatic. For PrintWriter, this example:

File("somefile.txt").printWriter().use { out ->
    history.forEach {
        out.println("${it.key}, ${it.value}")
    }
}

The for loop, or forEach depends on your style. No reason to use append(x) since that is basically write(x.toString()) and you already give it a string. And println(x) basically does write(x) after converting a null to "null". And println() does the correct line ending.

If you are using data classes of Kotlin, they can already be output because they have a nice toString() method already.

Also, in this case if you wanted to use BufferedWriter it would produce the same results:

File("somefile.txt").bufferedWriter().use { out ->
    history.forEach {
        out.write("${it.key}, ${it.value}\n")
    }
}

Also you can use out.newLine() instead of \n if you want it to be correct for the current operating system in which it is running. And if you were doing that all the time, you would likely create an extension function:

fun BufferedWriter.writeLn(line: String) {
    this.write(line)
    this.newLine()
}

And then use that instead:

File("somefile.txt").bufferedWriter().use { out ->
    history.forEach {
        out.writeLn("${it.key}, ${it.value}")
    }
}

And that's how Kotlin rolls. Change things in API's to make them how you want them to be.

Wildly different flavours for this are in another answer: https://stackoverflow.com/a/35462184/3679676