File handling CSV Tabular data

# CSV File Handling

The `klyn.io.csv` package provides an RFC-4180 style reader and writer. It handles quoted fields, delimiters, embedded newlines, doubled quotes, and common dialect options.

Imports

    import klyn.collections
    import klyn.io
    import klyn.io.csv

Reading Rows

`CSVReader` materializes rows as `ArrayList<String>` values. It can read a file name, a `Path`, or any `TextReader`.

    import klyn.collections
    import klyn.io
    import klyn.io.csv

    reader = CSVReader("contacts.csv", delimiter=';')
    reader.skip(1)  # Skip header row.

    for row as ArrayList<String> in reader:
        name = row[0]
        email = row[1]
        print(name + " <" + email + ">")

Writing Rows

`CSVWriter` can buffer output in memory or write directly to a file or text writer. Use `try` with file-backed writers so the file is closed deterministically.

    import klyn.io.csv

    try writer = CSVWriter("contacts.csv", delimiter=';'):
        writer.writeRow(["name", "email"])
        writer.writeRow(["Ada Lovelace", "ada@example.test"])
        writer.writeRow(["Grace Hopper", "grace@example.test"])

For diagnostics or tests, create a buffered writer and call `toString()`.

    writer = CSVWriter(',', '"', Char(0), true, "\n")
    writer.writeRow(["name", "note"])
    writer.writeRow(["Ada, A.", "uses \"quotes\""])
    print(writer.toString())

Dialects

The reader and writer expose the usual CSV knobs: delimiter, quote character, escape character, double-quote escaping, initial-space handling, line terminator, and quoting mode.

Option | Typical use
--- | ---
`delimiter` | Use `';'` for semicolon-separated files.
`skipInitialSpace` | Ignore spaces immediately after delimiters.
`quoting` | `minimal`, `all`, or `none` for writer output.
`strict` | Raise `CSVException` on malformed quoted fields.