OSDN Git Service

例外メッセージの追加,コーディングスタイルの修正
[karinto/karinto.git] / Karinto / CsvReader.cs
1 /*\r
2  *      Karinto Library Project\r
3  *\r
4  *      This software is distributed under a zlib-style license.\r
5  *      See license.txt for more information.\r
6  */\r
7 \r
8 using System;\r
9 using System.IO;\r
10 using System.Collections.Generic;\r
11 using System.Text;\r
12 using System.Text.RegularExpressions;\r
13 \r
14 \r
15 namespace Karinto\r
16 {\r
17     public class CsvReader<TDataSet> where TDataSet : IDataSet, new()\r
18     {\r
19         private string separator = ",";\r
20 \r
21         public string Separator\r
22         {\r
23             get { return separator; }\r
24         }\r
25 \r
26         /// <summary>\r
27         ///     区切り文字を指定する\r
28         ///     カンマ以外だったらCSVじゃないような...?\r
29         /// </summary>\r
30         /// <param name="separator">区切り文字(正規表現可)</param>\r
31         public void SetSeparator(string separator)\r
32         {\r
33             this.separator = separator;\r
34         }\r
35 \r
36         /// <summary>\r
37         ///     CSVファイルを読み込む\r
38         /// </summary>\r
39         /// <param name="path">CSVファイルのパス</param>\r
40         /// <param name="proto">行の雛型</param>\r
41         /// <returns>指定した型のリスト</returns>\r
42         public List<TDataSet> Read(string path)\r
43         {\r
44             return Read(path, new TDataSet());\r
45         }\r
46 \r
47         /// <summary>\r
48         ///     雛型を指定してCSVファイルを読み込む\r
49         /// </summary>\r
50         /// <param name="path">CSVファイルのパス</param>\r
51         /// <param name="proto">行の雛型</param>\r
52         /// <returns>指定した型のリスト</returns>\r
53         public List<TDataSet> Read(string path, TDataSet proto)\r
54         {\r
55             List<TDataSet> records = new List<TDataSet>();\r
56 \r
57             try\r
58             {\r
59                 using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))\r
60                 {\r
61                     using (StreamReader reader = new StreamReader(fs))\r
62                     {\r
63                         string line = "";\r
64                         // 数値にマッチする正規表現\r
65                         string rfloat = @"\s*([-+]?(?:[0-9]+(\.[0-9]*)?|(\.[0-9]+))([eE][-+]?[0-9]+)?)\s*";\r
66                         Regex rCsv = new Regex(rfloat + separator, RegexOptions.Compiled);\r
67 \r
68                         while (reader.Peek() >= 0)\r
69                         {\r
70                             line = reader.ReadLine() + separator;\r
71                             //Console.WriteLine("> " + line);\r
72                             MatchCollection mc = rCsv.Matches(line);\r
73 \r
74                             // 現状ではNaNが含まれる行は受理しない\r
75                             if (!proto.Width.Includes(mc.Count)) continue;\r
76 \r
77                             if (proto.KeyRange != null)\r
78                             {\r
79                                 double key = Double.Parse(mc[0].Groups[1].Value);\r
80                                 if (!proto.KeyRange.Includes(key)) continue;\r
81                             }\r
82 \r
83                             TDataSet c = new TDataSet();\r
84                             foreach (Match m in mc)\r
85                             {\r
86                                 c.Push(Double.Parse(m.Groups[1].Value));\r
87                             }\r
88                             records.Add(c);\r
89                         }\r
90                     }\r
91                 }\r
92             }\r
93             catch (Exception e)\r
94             {\r
95                 Console.WriteLine("The file could not be read:");\r
96                 Console.WriteLine("> " + path);\r
97                 Console.WriteLine(e.Message);\r
98                 throw e;\r
99             }\r
100 \r
101             return records;\r
102         }\r
103     }\r
104 }\r