読者です 読者をやめる 読者になる 読者になる

【C#】StreamReader#ReadLineの改行コードを明示的に指定する

ExcelAccessのデータをコピペしてExcelで保存、それで「CSVを作った」と言い張る輩が日本社会には巣食っているわけですが、あんなものはCSVに対する冒涜です。

と言うのも、セル内改行されているデータが「ダブルクォーテーションで括り、セル内改行部分はLFとして扱う」と言う本当にクソみたいな形式になるからです。

hoge,"fuga
piyo",foo,bar

StreamReader#ReadLineは改行コードがCRだろうがLFだろうがCRLFだろうが一行とみなしてくれるイカしたやつなんですが、このようなぶっ壊れたクソCSVに対してはあまりにも無力です。

ReadLineに改行するデリミタを受け取ってくれるオーバーロードがあればなぁ、でもそんなの普通使わないもんなぁ、と思いながら、拡張メソッドで実装したスニペットを載せておきます。

コード

public static class StreamReaderExtention
{
    public static string ReadLine(this StreamReader sr, string delimiter)
    {
        var sb = new StringBuilder();
        var buf = new char[1];
        var chars = new StringBuilder();
        var isLineEnd = false; 

        do
        {
            sr.Read(buf, 0, 1);
            sb.Append(buf);
            chars.Append(buf);

            if (!delimiter.StartsWith(chars.ToString()))
            {
                chars.Clear();
            }
            else
            {
                if (delimiter == chars.ToString()) isLineEnd = true;
            }

        } while (!sr.EndOfStream && !isLineEnd);

        if(isLineEnd) sb = sb.Remove(sb.Length - delimiter.Length, delimiter.Length);

        return sb.ToString();
    }
}

class Program
{
    static void Main(string[] args)
    {
        var IN = @"C:\test.txt";

        using (var sr = new StreamReader(IN, Encoding.UTF8))
        {
            while (!sr.EndOfStream)
            {
                Console.WriteLine(sr.ReadLine("\r\n"));
            }
        }

    }
}

まとめ

ExcelCSVを作るな。ExcelCSVを開くな。