簡體   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