Skip to content

/commands/kotlin/read-file-line-by-line

kotlin read a file line by line (readLines, useLines, forEachLine)

The commands on this page have not been executed by our verification runner yet.updated
tool
Kotlin
versions
Kotlin 1.0+ (JVM)
os
any

In Kotlin/JVM, File("data.txt").readLines() returns all lines of a file as a List<String>, and File("data.txt").forEachLine { println(it) } processes them one at a time. For large files use useLines { lines -> ... }, which gives you a lazy Sequence<String> and closes the file when the block ends. All of them read UTF-8 by default and drop the line terminators.

Examples

ReadLines.kt
import java.io.File

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

    // Small files: everything in memory as List<String>
    val lines = file.readLines()
    println("${lines.size} lines, first: ${lines.firstOrNull()}")

    // Any size: one line at a time
    file.forEachLine { line -> println(line.uppercase()) }

    // Any size, with sequence operations; the file is closed after the block
    val errors = file.useLines { seq -> seq.filter { "ERROR" in it }.count() }
    println("$errors error lines")

    // Whole file as one String
    val text = file.readText()
    println(text.length)
}

Choosing a function

FunctionReturnsUse it when
File.readLines()List<String>The file is small and you need random access to lines
File.forEachLine { }UnitYou only need to process each line once
File.useLines { seq -> }Whatever the block returnsLarge files with filter, map or take; the file is closed afterwards
File.readText()StringYou need the whole content as one string
File.bufferedReader().use { it.readLine() }String?Read only the first line, or full control over reading
generateSequence(::readLine)Sequence<String>Read standard input line by line

Pitfalls

  • Escaping the sequence. The sequence from useLines is only valid inside the block: returning it and iterating later fails because the reader is already closed. Turn it into a list (seq.toList()) or compute the result inside the block.
  • Missing files. File("missing.txt").readLines() throws java.io.FileNotFoundException. Check file.exists() first or catch the exception.
  • Relative paths. A relative path is resolved against the working directory of the JVM, which for ./gradlew run is the subproject folder, not necessarily the folder you expect. Print file.absolutePath when a file is not found.
  • Kotlin Multiplatform. java.io.File exists only on the JVM (and Android); common code needs a library such as kotlinx-io or Okio.
  • Numbers in lines must be parsed, see convert a string to an Int.

Confirm it worked

Print lines.size and compare it with the line count your editor shows for the file. A final newline does not add an empty entry, but blank lines inside the file come back as empty strings; drop them with lines.filter { it.isNotBlank() } if they do not matter.

FAQ

Which encoding does readLines use?

UTF-8 by default. Pass another charset when the file uses one, for example File(path).readLines(Charsets.ISO_8859_1).

Are the line endings included in each line?

No. The functions split on \n, \r\n and \r and return the lines without the terminators, so files with Windows line endings need no extra handling.

Why do I get Unresolved reference: readLines?

readLines, useLines and forEachLine are extension functions on java.io.File in kotlin.io. Import java.io.File and call them on a File, not on a String path.

Sources