如何在Kotlin中读取纯文本文件?

Ani*_*bla 3 file text-files bufferedreader kotlin

在Kotlin中,可能会有多种方式读取纯文本文件。

我想知道什么是可能的方式以及如何使用它们。

kat*_*uke 9

我认为最简单的编码方式是使用 kotlin.text 和 java.io.File

import java.io.File

fun main(args: Array<String>) {
    val text = File("sample.txt").readText()
    println(text)
}
Run Code Online (Sandbox Code Playgroud)

  • 对于大文件不建议使用此方法。它的内部文件大小限制为 2 GB。 (5认同)
  • @ArtOfWarfare 我只是想指出一个事实。是否拥有 2 GB 文本文件的现实或逻辑是另一个讨论。 (2认同)

Ani*_*bla 7

  1. 使用BufferedReader

    import java.io.File
    import java.io.BufferedReader
    
    fun main(args: Array<String>) {
        val bufferedReader: BufferedReader = File("example.txt").bufferedReader()    
        val inputString = bufferedReader.use { it.readText() }
        println(inputString)
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 使用InputStream

    按行阅读

    import java.io.File
    import java.io.InputStream
    
    fun main(args: Array<String>) {
        val inputStream: InputStream = File("example.txt").inputStream()
        val lineList = mutableListOf<String>()
    
        inputStream.bufferedReader().useLines { lines -> lines.forEach { lineList.add(it)} }
        lineList.forEach{println(">  " + it)}
    }
    
    Run Code Online (Sandbox Code Playgroud)

    阅读所有行

    import java.io.File
    import java.io.InputStream
    
    fun main(args: Array<String>) {
        val inputStream: InputStream = File("example.txt").inputStream()
        val inputString = inputStream.bufferedReader().use { it.readText() }
        println(inputString)
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 直接使用文件

    import java.io.File
    import java.io.BufferedReader
    
    fun main(args: Array<String>) {
        val lineList = mutableListOf<String>()
    
        File("example.txt").useLines { lines -> lines.forEach { lineList.add(it) }}
        lineList.forEach { println(">  " + it) }
    }
    
    Run Code Online (Sandbox Code Playgroud)


gid*_*dds 7

Anisuzzaman 的回答列出了几种可能性。

\n\n

它们之间的主要区别在于文件是否作为单个字符串读入内存,读入内存并分成行,还是逐行读取。

\n\n

显然,一次性将整个文件读入内存可能会占用更多内存,因此除非确实有必要,否则应该避免这种情况。\xc2\xa0(文本文件可以变得任意大!)\xc2\ xa0 所以逐行处理BufferedReader.useLines()通常是一个好方法。

\n\n

其余的差异主要是历史性的。\xc2\xa0 Java 的早期版本使用InputStream&c,它不能正确区分字符和字节;Reader添加 &c 是为了纠正这个问题。\xc2\xa0 Java 8 添加了使用流更有效地逐行读取的方法(例如Files.lines())。\xc2\xa0 最近,Kotlin 添加了自己的扩展函数(例如BufferedReader.useLines()),这使得那就更简单了。

\n


Sim*_*ert 5

上面的答案都是基于 Kotlin Java 的。这是读取文本文件的 Kotlin Native 方式:

val bufferLength = 64 * 1024
val buffer = allocArray<ByteVar>(bufferLength)

 for (i in 1..count) {
    val nextLine = fgets(buffer, bufferLength, file)?.toKString()
    if (nextLine == null || nextLine.isEmpty()) break

    val records = parseLine(nextLine, ',')
    val key = records[column]
    val current = keyValue[key] ?: 0
    keyValue[key] = current + 1
}


fun parseLine(line: String, separator: Char) : List<String> {
    val result = mutableListOf<String>()
    val builder = StringBuilder()
    var quotes = 0
    for (ch in line) {
        when {
            ch == '\"' -> {
                quotes++
                builder.append(ch)
            }
            (ch == '\n') || (ch ==  '\r') -> {}
            (ch == separator) && (quotes % 2 == 0) -> {
                result.add(builder.toString())
                builder.setLength(0)
            }
            else -> builder.append(ch)
        }
    }
    return result
}
Run Code Online (Sandbox Code Playgroud)

请参阅:https : //github.com/JetBrains/kotlin-native/blob/master/samples/csvparser/src/csvParserMain/kotlin/CsvParser.kt