LoginSignup
5
2

More than 1 year has passed since last update.

KotlinでCSVならkotlin-csvが素敵というお話

Posted at

 さてCSV。自分で実装するには意外と複雑なのがCSV。

 データ内にダブルクォートを入れる場合はダブルクォートでエスケープするとか、ダブルクォートで囲ったら改行コードもデータにできるとか。

 そういう意外と面倒なCSV、使いやすいライブラリはございませんでしょうかと、色々使ってみたところkenta.koyamaさんのkotlin-csvが凄く素敵で素晴らしかったというお話。

About
Pure Kotlin CSV Reader/Writer

 Pure kotlin! ああ、なんと美しい響きでしょう。

ではbuild.gradleから

build.gradle
implementation 'com.github.doyaaaaaken:kotlin-csv-jvm:1.1.0'

今回のテストコードを動かすための依存関係

build.gradle
testImplementation "org.spekframework.spek2:spek-dsl-jvm:2.0.17"
testRuntimeOnly "org.spekframework.spek2:spek-runner-junit5:2.0.17"

testImplementation 'com.google.truth:truth:1.1.3'
testImplementation 'com.google.truth.extensions:truth-java8-extension:1.1.3'
testImplementation 'com.google.testing.compile:compile-testing:0.19'

実際のテストコード

CsvReadTest.kt
import com.github.doyaaaaaken.kotlincsv.dsl.csvReader
import com.google.common.truth.Truth
import org.spekframework.spek2.Spek
import org.spekframework.spek2.style.specification.describe
import java.nio.charset.Charset
import java.nio.file.Path
import kotlin.io.path.createTempDirectory
import kotlin.io.path.createTempFile
import kotlin.io.path.writeText

class CsvReadTest: Spek({
    describe("kotlin-csvを使ったCSVファイル読み込み") {

        // 取り敢えず文字列をパースして表示してみる
        context("シンプルに読み込みと表示") {
            val data = """
                ナリタブライアン,マヤノトップガン,"カンマ,入り","改行
                入り"
                "キタサンブラック","コントレイル",,"ダブル""クォートいり"
            """.trimIndent()

            csvReader().readAll(data).forEach {
                println(it.joinToString(";"))
            }
        }

        // 文字コード指定でMS932のファイルを読み込んで見る
        context("MS932ファイル読み込みテスト") {
            temporaryDirectory { dir ->
                csvReader {
                    charset = "MS932" // 文字コード指定を試すため今回は敢えてMS932で読み込み
                }.readAll(
                    createTempFile(dir).apply {
                        writeText("""
                            ナリタブライアン,マヤノトップガン,"カンマ,入り","改行
                            入り"
                            "キタサンブラック","コントレイル",,"ダブル""クォートいり"
                        """.trimIndent(), Charset.forName("MS932"))
                    }.toFile()
                ).joinToString("[CRLF]") {
                    it.joinToString(";")
                }.let {
                    // 検証
                    Truth.assertThat(it).isEqualTo("""
                        ナリタブライアン;マヤノトップガン;カンマ,入り;改行
                        入り[CRLF]キタサンブラック;コントレイル;;ダブル"クォートいり
                    """.trimIndent())
                }
            }
        }
    }
}) {
    companion object {
        // こういうの探せばありそうですけどね, JUnit使ってた時は@TempDirとか使ってましたね
        fun temporaryDirectory(closure: (Path)->Unit) {
            val dir = createTempDirectory()
            runCatching {
                closure(dir)
            }.onFailure { throw it }
             .also { dir.toFile().deleteRecursively() }
        }
    }
}

 色々試した上で、こちらを使わせていただくことになりました。

 Pure Kotlin! 世界の全てをkotlinで が合言葉の私の胸に、ズンズンズン、クリティカルヒット(やった!)でございしたとさ。

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2