kotlinでCSVファイル(金沢のオープンデータ)を読み取る

## はじめに
今回はkotlinでCSVを読み取る機会があったので、この記事にまとめます。
最初はライブラリを使おうと思いopenCSVなど使ってみたのですが、途中でエラーが出て断念。
他にもライブラリはいくつかあったんですが今回使わずやってみました。
ちなみに環境はAndroidStudioです。
もしかしたら今度ライブラリを使ってみた記事をあげるかもしれません。
## 調べたライブラリ
- https://commons.apache.org/proper/commons-csv/ 
 
- https://qiita.com/ohwada/items/06fb2ffbb1b17e4a5626#apache-commons-csv
この方が書いている記事と同じエラーでお腹を痛める。
## 今回の完成品  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255216/d5184257-9f3c-dbc3-12ac-c03caeb49035.png)
やってることはCSVファイルにある名前と概略をリストに表示させてるだけです。

## 最初にやること
1. AndroidStudioでプロジェクトを立ち上げる。
2. 今回はKanazawaオープンデータのCSVを読み取ります。下記からCSVを適当に取ってきます。  
https://www4.city.kanazawa.lg.jp/13021/opendata/renkei.html
3. CSVをプロジェクトの/app/src/assets/配下に置く。assetsフォルダがなかったら作りましょう。
(File -> new -> Directory -> assetsフォルダを作成)  
今回使うCSVファイルは避難所のやつです。
![スクリーンショット 2019-12-04 15.59.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255216/40e778c4-b296-95e7-4cb2-6592f76d30b0.png)

## 今回主にいじるファイル
#### layout
- activity_main.xml   

#### kotlinファイル
- MainActivity.kt
- Shelter.kt(今回は避難所データを持ってくるのでShelterにしてみました。)

## ListViewを作る
まずactivity_mainにListViewを配置します。

```xml:activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:orientation="vertical">

    <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:text="@string/title"
        android:textAlignment="center"
        />
    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />
</LinearLayout>
```

## data classを作る
次にCSVのデータを格納するデータクラスを作ります。
データクラスについては下の記事がとても参考になったので記させていただきます。
https://blog.y-yuki.net/entry/2019/05/30/003000
避難所なのでShelter.ktにしました。ここはcsvのデータによってお好みでどうぞ
今回は名称と概略のみ表示させるのでnameとoverviewカラムのみ作成します。

```kotlin:Shelter.kt
data class Shelter (
    //名称,概略
    var name: String? = null,
    var overview: String? = null
){}
```

## MainActivity.ktを作る
このファイルでCSVの読み取りと表示をします。

```kotlin:MainActivity.ktclass 
class MainActivity : AppCompatActivity() {
    //1行目が格納される。
    var column: Array<String> = emptyArray<String>()
    //shelterインスタンスが格納される
    var shelters: Array<Shelter> = emptyArray()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        //csvの読み取り
        readCsv("shisetsu_hinan.csv")
        // ListViewの表示
        val listView: ListView = findViewById(R.id.listView)
        val listItems: Array<String> = setItem(shelters)
        val adapter = ArrayAdapter(this,android.R.layout.simple_listItem_1,listItems)
        listView.adapter = adapter
    }

    //assetsからshisetsu_hinan.csvを持ってくる
    fun readCsv(filename: String){
        try {
            val file = resources.assets.open(filename)
            val fileReader = BufferedReader(InputStreamReader(file))
            var i: Int = 0
            fileReader.forEachLine {
                if (it.isNotBlank()) {
                    if (i == 0) {
                        //1行目だけ別の配列に読み取る。
                        column = it.split(",").toTypedArray()
                    } else {
                        //2行目以降
                        val line = it.split(",").toTypedArray()
                        fetchCSV(line)
                    }
                }
                i++;
            }
        }catch (e: IOException) {
            //例外処理
            print(e)
        }
    }
    //Shelters配列にshelterインスタンスを格納
    fun fetchCSV(line: Array<String>){
            val shelter = Shelter(
                name = line[10],
                overview = line[11]
            )
            //sheltersに全ての避難所を格納
            shelters += shelter
    }
    //リストに表示する文字列をセット
    fun setItem(shelters: Array<Shelter>): Array<String>{
        var items: Array<String> = emptyArray()
        shelters.forEach {
            items += """
                |避難所名:{${it.name}}
                |概要:{${it.overview}}""".trimMargin()
        }
        return items

    }
}
```

**やってること**
1. readCSV関数でCSVの読み取りをしています。1行ずつ読み取って最終的にSheltersに格納されます。
2. listViewに表示する文字列をセット。setItems関数でリストに表示する文字列を設定しています。
3. 最後にlistviewにアイテムをセットしています。

## まとめ
今回はライブラリを使わずにやってみました。めんどくさくて全てのカラムを格納とはいきませんでしたがまたdataクラスとCSVを関連づけしてくれるライブラリの記事を時間があったら書こうと思います。
いいライブラリや記事があったら教えてください。