torutkのブログ

ソフトウェア・エンジニアのブログ

CSVファイルが好きな人たち

プログラム間でのファイルのやり取りや、人間系で作成したデータをプログラムに読み込ませるとき、仕事上でよくCSVファイルにしようとする人に直面します。(というか、CSVファイル以外を採用する人にあうことは稀)

CSVファイルというだけでは、ファイルフォーマットを決めたことにはならず、プログラムで扱えるようにするには、いくつも決めなければいけないことがあります。

  • 文字コード
  • 改行コード
  • 文字列をダブルクォートで囲むか否か
  • 文字列中にダブルクォートおよび改行が含まれる場合の扱い
  • 数値の表現方法(符号、小数点形式)
  • 日時の表現方法

そもそもCSV形式といっても明確な仕様は存在してなく、数年前にRFC 4180でCSV形式について文書が出されている程度です(なぜかRFCなんだろうか?という疑問が生じますが)。

でも、このような決め事をせずに作ってしまい、あとでいろいろ問題が発生するというアンチパターンを繰り返しています。

また、CSVを好む人はたいていExcelCSVファイルを作成するようです。そのような場合、フォーマットは「Excelに合わせる」みたいな、それでExcelがどんなCSVを吐くかきちんと確認していないということが横行して大変なことがあります。

ありがちなのが、

  • UNIX系で動くプログラムなのに、ExcelCSVデータを作って、文字コードの違い、改行コードの違いでバグになる(読み取った文字列を画面にだすと化けたり、最後のカラムの文字列にCRコードが付いてしまい誤動作するなど)
  • 空白のトリムをし忘れて、空白なく詰めて書いたテストデータでは動くが(たいてい空白のトリムを忘れる人はCSVを作るときに空白は入れない)、他で作られたCSVファイルで誤動作する
  • Excelはセル内で改行できるので、それをcsv形式で保存すると・・・
    • セル内改行はLFになるっぽい
  • 文字列内にカンマを使うこともあるだろうけど、行の文字列を単純にカンマでスプリットすると大変なことに・・・

また、CSVファイルの読み書き処理を、単純な例だけに対応する自前のやっつけパーサーを書いてしまい、あとではまるといったことがあります。

他にも、列の位置でデータを決めているので、あとで不要になった列も削除すると各プログラムを改修しなくてはならないので、「この列は未使用」みたいな暗黙ルールがどんどん出ます。そして、最後の列に新たな項目を足していくので、だんだん順番に意味的な脈絡がなくなり、また、追加した列が「ある特定プログラムだけで使用」だと、「この列はこのプログラムでは使うが他では未使用」とさらに暗黙ルールが積み重なります。

ということで、何が言いたかったかというと、安易にCSVを選択すると、将来に大きな負債を残します、ということです。