【C#】StreamReader#ReadLineの改行コードを明示的に指定する
ExcelやAccessのデータをコピペして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")); } } } }