Sobes.tech
Middle

How to work with files and input-output streams (I/O) in Kotlin?

sobes.tech AI

Answer from AI

The Kotlin standard library provides convenient extensions for working with I/O, simplifying interactions with java.io.

Main approaches and classes:

  • Reading from a file:

    • File.readBytes(): Reads the file content into a byte array.
    • File.readText(): Reads the file content as a string (considering encoding).
    • File.forEachLine { ... }: Processes each line of the file.
    • File.bufferedReader(): Creates a BufferedReader for line-by-line reading.
    • File.inputStream(): Creates an InputStream for reading bytes.
  • Writing to a file:

    • File.writeBytes(bytes): Writes a byte array to a file.
    • File.writeText(text, append): Writes a string to a file. Use append = true to add at the end.
    • File.printWriter(): Creates a PrintWriter for convenient formatted text output.
    • File.outputStream(): Creates an OutputStream for writing bytes.
  • Working with streams:

    • InputStream.bufferedReader(): Wraps an InputStream in a BufferedReader.
    • OutputStream.printWriter(): Wraps an OutputStream in a PrintWriter.
    • Extension functions like copyTo(outputStream) for copying stream contents.
  • Resource handling (closures):

    • Extension functions use { ... } for automatic closing of streams and readers/writers, even in case of exceptions.
import java.io.File

fun main() {
    val file = File("my_file.txt")

    // Writing to a file
    file.writeText("Hello, Kotlin I/O!")
    file.appendText("\nContinuation of the line.")

    // Reading the file line by line
    file.forEachLine { line ->
        println(line)
    }

    // Reading the entire file as a string
    val content = file.readText()
    println("\nEntire file content:")
    println(content)

    // Using bufferedReader with use
    file.bufferedReader().use { reader ->
        reader.lines().forEach(::println) // Reading via Java Stream API
    }

    // Copying the file
    val newFile = File("my_file_copy.txt")
    file.inputStream().use { input ->
        newFile.outputStream().use { output ->
            input.copyTo(output) // Convenient stream copying
        }
    }
}

Comparison table of some methods:

Method Purpose Data type Line-by-line / Whole Note
readBytes() Read into bytes ByteArray Whole Suitable for binary data
readText() Read as a string String Whole Convenient for text files
forEachLine { } Process each line String Line-by-line Ideal for large text files
bufferedReader() Create a buffered reader N/A Stream-based Flexible control, requires use
writeBytes() Write bytes ByteArray Whole Suitable for binary data
writeText() Write a string String Whole/Append Convenient for text files
printWriter() Create a writer with formatting N/A Stream-based Useful for formatted output, requires use

Using use { ... } is key for safe I/O operations in Kotlin, ensuring resource release. Kotlin extends existing Java classes (File, InputStream, OutputStream, etc.) with convenient functions.

How to work with files and input-output streams (I/O)… - sobes.tech