繁体   English   中英

Kotlin 如何读写 CSV 文件

[英]Kotlin How to read and write CSV file

你能给我最简单的 Kotlin 代码吗?

我试图找到用谷歌搜索的好例子,5 小时或更长时间后,我找不到我想要的东西。

我找不到任何可以通过 Google 搜索复制和粘贴的代码。

我在书中也找不到任何适用的描述。

这对于中级或高级用户来说可能很容易,但对我来说很难。

如果您愿意为初学者解释这一点,请分享您的时间。

我想像这张照片一样更新已解决测验的完成标记。

from chk[1] to chk[20]

not yet : 0
done : 2 
// 2 is similar Victory Sign.

例如,如果解决了测验编号“1”

chk[1] = 2

var chk_Q: Array<Int> = arrayOf (
    0,
    0, 0, 0, 0, 0,
    0, 0, 0, 0, 0,
    0, 0, 0, 0, 0,
    0, 0, 0, 0, 0,
)

现在,当应用程序处于活动状态时,保留数据 0 或 2。但是,一旦应用程序完成,chk_Q 1到 [20] 就会回到 0。

所以,我想将数据保存在 checkDone.csv 中。

我的教科书没有解释如何保存和读取 CSV 文件。

波纹管代码没有按我的意愿工作。

openFileOutput("checkDone.csv", MODE_PRIVATE)
         .bufferedWriter().use {
             for (i in 1..10) {
                 it.write(chk_Q[i].toString())
             }
         }
openFileInput("checkDone.csv", MODE_PRIVATE)
        .bufferedReader().forEachLine {
            str.append(it)
            str.append(System.getProperty("line.separator"))
        }

==================================================== =

<2022 年 6 月 2 日添加>

使用文本文件完成

==================================================== =

MainActivity.kt

==================================================== =

package com.surlofia.csv_exists_write_read

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.surlofia.csv_exists_write_read.databinding.ActivityMainBinding
import java.io.*

var chk_Q: Array<Int> = arrayOf (
    0,
    0, 0, 0, 0, 0,
    0, 0, 0, 0, 0,
    0, 0, 0, 0, 0,
    0, 0, 0, 0, 0,
)

class MainActivity : AppCompatActivity() {

    // View Binding Class のインスタンス
    // lateinit で宣言し初期化タイミングを onCreate() まで遅らせる
    // activity_main.xml の場合、ActivityMainBinding
    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // setContentView(R.layout.activity_main) をコメントに変えた

        // bindingのイニシャライズ
        // super.onCreate(savedInstanceState) 直下に書く!!
        // Binding Classに含まれる静的 inflate() メソッドを呼び出す
        binding = ActivityMainBinding.inflate(layoutInflater)

        // root view への参照を取得
        val view = binding.root

        // view をsetContentView()にセット
        setContentView(view)

        // bindingのイニシャライズ 完了


        // Android - ファイル入出力の例(Read、Write、内部、外部ストレージ)
        // https://codechacha.com/ja/android-read-write-file/

    // Load saved data at game startup.
    // ゲーム起動時に、セーブデータを読み込んでおく
    val filePath = filesDir.path + "/memo.dat"
    val file = File(filePath)

    if (isFileExists(file)) {
        readTextFromFile(filePath)
    }

    // Game Program Run

    // and save Data
    writeTextToFile(filePath)

        binding.fileExists.text = isFileExists(file).toString()


    }



    // Kotlinにファイルが存在するかどうかを確認します
    // https://www.techiedelight.com/ja/check-if-a-file-exists-in-kotlin/

    private fun isFileExists(file: File): Boolean {
        return file.exists() && !file.isDirectory
    }


    // Android - ファイル入出力の例(Read、Write、内部、外部ストレージ)
    // https://codechacha.com/ja/android-read-write-file/
    // &
    // TECHNICAL MASTER はじめてのAndroidアプリ開発 Kotlin編 (TECHNICAL MASTER 98)
    // https://www.amazon.co.jp/dp/B09MHF7F6N/ref=dp_kinw_strp_1

    private fun readTextFromFile(path: String) {
        val file = File(path)
        val fileReader = FileReader(file)
        val bufferedReader = BufferedReader(fileReader)

        /*
        val readString = StringBuilder()

        bufferedReader.forEachLine {
            readString.append(it)
            readString.append(System.getProperty("line.separator"))
        }

        binding.readFile.text = readString

         */

        // Let'sプログラミング
        // Home › Java入門 › テキストファイルの入出力
        // まとめてテキストを読む
        // https://www.javadrive.jp/start/stream/index3.html

        chk_Q[0] = 0

        for (i in 1 .. 20) {
            chk_Q[i] = bufferedReader.readLine().toInt()
        }
        bufferedReader.close()


        var tempString = ""

        for(i in 0 .. 20) {
            tempString = tempString +i + "-->" + chk_Q[i] + "\n"
        }

        binding.readFile.text = tempString

    }

    // Android - ファイル入出力の例(Read、Write、内部、外部ストレージ)
    // https://codechacha.com/ja/android-read-write-file/

    private fun writeTextToFile(path: String) {
        val file = File(path)
        val fileWriter = FileWriter(file, false)
        val bufferedWriter = BufferedWriter(fileWriter)


        for (i in 0 .. 20) {
            chk_Q[i] = 2
            bufferedWriter.append(chk_Q[i].toString())
            bufferedWriter.newLine()
        }

        bufferedWriter.close()

        /*
        bufferedWriter.append("Test1\n")
        bufferedWriter.append("Test2")
        bufferedWriter.newLine()
        bufferedWriter.append("Test3\n")
        bufferedWriter.close()

         */


    }
}

====================================

activity_main.xml

====================================

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/fileExists"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="Hello World!"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/readFile"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="16dp"
        android:text="TextView"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/fileExists" />

</androidx.constraintlayout.widget.ConstraintLayout>

关于使用 Apache Commons 读取 CSV 的教程是在假设您正在为 JVM 而不是 Android 编写的情况下编写的。 让它适应安卓并不简单。 我认为 Apache Commons 库无论如何都不是必需的,因为 CSV 是一种如此简单的基于文本的格式。

这里有几个简单的扩展函数,可以在文件上调用它们来读取 CSV 作为二维字符串列表,或者将二维字符串列表写入文件。 将二维列表视为数据行列表。 内部列表中的每个值都是该行中的所有值。

@Throws(IOException::class)
fun File.readAsCSV(): List<List<String>> {
    val splitLines = mutableListOf<List<String>>()
    forEachLine {
        splitLines += it.split(", ")
    }
    return splitLines
}

@Throws(IOException::class)
fun File.writeAsCSV(values: List<List<String>>) {
    val csv = values.joinToString("\n") { line -> line.joinToString(", ") }
    writeText(csv)
}

您不应该在主线程上执行文件 IO 操作,因为这会冻结 UI 并有可能使您的应用程序因应用程序无响应错误而崩溃。 看起来你有某种游戏循环,所以我不确定如何在你的情况下应用这个建议。

以下是使用 FileInputStream 和 FileOutputStream 的上述函数的替代版本,因此它们在 Android 上更加通用(因为您无法直接访问某些存储位置的文件):

@Throws(IOException::class)
fun FileInputStream.readAsCSV() : List<List<String>> {
    val splitLines = mutableListOf<List<String>>()
    reader().buffered().forEachLine {
        splitLines += it.split(", ")
    }
    return splitLines
}

@Throws(IOException::class)
fun FileOutputStream.writeAsCSV(values: List<List<String>>) {
    val csv = values.joinToString("\n") { line -> line.joinToString(", ") }
    writer().buffered().use { it.write(csv) }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM