2011-10-09 102 views
2

我知道如何读取和显示.csv文件的一行。现在我想解析该文件,将其内容存储在数组中,并将这些数组用作我创建的某些类的值。将CSV数据导入到C#类中

我想知道如何。

下面是一个例子:

basketball,2011/01/28,Rockets,Blazers,98,99 
baseball,2011/08/22,Yankees,Redsox,4,3 

正如可以看到的,每个字段由逗号分隔。我创建了Basketball.cs和棒球类这是Sport.cs类的扩展,它具有以下字段:

private string sport; 
private string date; 
private string team1; 
private string team2; 
private string score; 

我明白,这是简单的,而且还有存储这些信息的更好的方法,即为每个团队创建类,使日期成为DateType数据类型,以及更多相同的内容,但我想知道如何将这些信息输入到类中。

我假设这与getter和setters有关...我也读过字典和集合,但我想通过将它们全部存储在数组中...(如果有道理......随时纠正我)。

这是我到目前为止。它所要做的就是读取csv和parrot在控制台上的内容:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.IO; 

namespace Assign01 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      string line; 
      FileStream aFile = new FileStream("../../sportsResults.csv", FileMode.Open); 
      StreamReader sr = new StreamReader(aFile); 

      // read data in line by line 
      while ((line = sr.ReadLine()) != null) 
      { 
       Console.WriteLine(line); 
       line = sr.ReadLine(); 
      } 
      sr.Close(); 
     } 
    } 
} 

帮助将不胜感激。

回答

6

创建数组以保留信息不是一个好主意,因为您不知道将有多少行将在输入文件。你的数组的初始大小是多少?我建议您使用例如通用列表来保存信息(例如列表<>)。

您还可以添加一个构造函数,如上面的回答描述了接受一个数组(分裂作用的结果,你的体育类。

另外,你可以提供一些转换的制定者

public class Sport 
{ 
    private string sport; 
    private DateTime date; 
    private string team1; 
    private string team2; 
    private string score; 

    public Sport(string[] csvArray) 
    { 
     this.sport = csvArray[0]; 
     this.team1 = csvArray[2]; 
     this.team2 = csvArray[3]; 
     this.date = Convert.ToDateTime(csvArray[1]); 
     this.score = String.Format("{0}-{1}", csvArray[4], csvArray[5]); 
    } 

为了简单起见,我写了Convert Method,但请记住,除非您确定DateField始终包含有效日期,Score总是包含Numeric Values,否则这不是一种非常安全的方法。您可以尝试其他更安全的方法,如tryParse或某些Exception处理。

我所有的诚实,它必须补充说,上述解决方案很简单(按要求),在概念层面上,我会建议不要这样做。将属性与csv文件之间的映射逻辑放在类中会使运动类过于依赖文件本身,因此不易重用。任何后来的文件结构变化都应该反映在你的课堂上,而且经常会被忽视。因此,这将是明智的把你的“映射&转换”的逻辑在主程序中,并保持你的类清洁尽可能

(改变了你的“分数”的问题被格式化为2串用连字符组合)

+0

我不会真的把得分作为一个整数,因为它是两个整数相比......即99-98。但我很欣赏这个答案。谢谢。 – iggy2012

3

尽管有许多库可以让csv阅读变得简单(请参阅:here),但您现在需要做的就是分割它。

String[] csvFields = line.Split(","); 

现在每个字段分配给相应的成员

sport = csvFields[0]; 
date = csvFields[1]; 
//and so on 

这每次读一个新行时间将然而覆盖值,所以你需要收拾值成一类,并保存实例这个班级的名单。

+0

当你说包装值到一个类,并将实例保存到列表中,你究竟是什么意思? – iggy2012

+1

请参阅用户936598评论课程的外观。然后创建一个''''列表 sports = new列表()''''在进入lop之前使用''''sports.Add(new Sport(line.split(“,”)));'' '在while循环中添加它。 – Darcara

0

下面是大多数新手喜欢尝试和错误 请不要新手,醒目的解决方案;别忘了在你的cs文件添加System.Core.dll在引用 导入命名空间:using System.Linq的;

也许添加迭代器将是更好的代码

private static IEnumerable<String> GetDataPerLines() 
{ 
    FileStream aFile = new FileStream("sportsResults.csv",FileMode.Open);    
    StreamReader sr = new StreamReader(aFile); 
    while ((line = sr.ReadLine()) != null)    
    { 
     yield return line; 
    }    
    sr.Close(); 
} 

static void Main(string[] args) 
{ 
    var query = from data in GetDataPerLines() 
      let splitChr = data.Split(",".ToCharArray()) 
       select new Sport 
    { 
     sport = splitChr[0], 
     date = splitChr[1],.. and so on 
    } 

    foreach (var item in query) 
    { 
     Console.Writeline(" Sport = {0}, in date when {1}",item.sport,item.date); 
    } 
} 

也许这样,样品上面创建一个使用产自己的迭代(请查看MSDN文档说),并创建集合根据您的字符串。

让我知道,如果我写错了代码,因为我没有;当我写答案时没有Visual Studio。 为了您的所知,像“Sport []”这样的数组一维将转化为CLR IEnumerable

6

将sting分解为数组以获取数据可能容易出错并且速度很慢。尝试使用OLE数据提供程序来读取CSV,就好像它是SQL数据库中的表一样,这样您就可以使用WHERE子句来过滤结果。

 
App.Config 
<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <connectionStrings> 
    <add name="csv" providerName="System.Data.OleDb" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source='C:\CsvFolder\';Extended Properties='text;HDR=Yes;FMT=Delimited';" /> 
    </connectionStrings> 
</configuration> 

program.cs 

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Data.OleDb; 
using System.Configuration; 
using System.Data; 
using System.Data.Common; 

namespace CsvImport 
{ 
    class Stat 
    { 
     public string Sport { get; set; } 
     public DateTime Date { get; set; } 
     public string TeamOne { get; set; } 
     public string TeamTwo { get; set; } 
     public int Score { get; set; } 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      ConnectionStringSettings csv = ConfigurationManager.ConnectionStrings["csv"]; 
      List stats = new List(); 

      using (OleDbConnection cn = new OleDbConnection(csv.ConnectionString)) 
      { 
       cn.Open(); 
       using (OleDbCommand cmd = cn.CreateCommand()) 
       { 
        cmd.CommandText = "SELECT * FROM [Stats.csv]"; 
        cmd.CommandType = CommandType.Text; 
        using (OleDbDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection)) 
        { 
         int fieldSport = reader.GetOrdinal("sport"); 
         int fieldDate = reader.GetOrdinal("date"); 
         int fieldTeamOne = reader.GetOrdinal("teamone"); 
         int fieldTeamTwo = reader.GetOrdinal("teamtwo"); 
         int fieldScore = reader.GetOrdinal("score"); 

         foreach (DbDataRecord record in reader) 
         { 
          stats.Add(new Stat 
          { 
           Sport = record.GetString(fieldSport), 
           Date = record.GetDateTime(fieldDate), 
           TeamOne = record.GetString(fieldTeamOne), 
           TeamTwo = record.GetString(fieldTeamTwo), 
           Score = record.GetInt32(fieldScore) 
          }); 
         } 
        } 
       } 
      } 

      foreach (Stat stat in stats) 
      { 
       Console.WriteLine("Sport: {0}", stat.Sport); 
      } 
     } 
    } 
} 

 

编辑

我忘了展示CSV应该如何看:)

 
stats.csv 

sport,date,teamone,teamtwo,score 
basketball,28/01/2011,Rockets,Blazers,98 
baseball,22/08/2011,Yankees,Redsox,4 
+0

这比我的理解还要进一步,我试着从简单开始,但我很欣赏它。 – iggy2012

1
// use "Microsoft.VisualBasic.dll" 

using System; 
using Microsoft.VisualBasic.FileIO; 

class Program { 
    static void Main(string[] args){ 
     using(var csvReader = new TextFieldParser(@"sportsResults.csv")){ 
      csvReader.SetDelimiters(new string[] {","}); 
      string [] fields; 
      while(!csvReader.EndOfData){ 
       fields = csvReader.ReadFields(); 
       Console.WriteLine(String.Join(",",fields));//replace make instance 
      } 
     } 
    } 
} 
0

这里是我做了一个类加载一个逗号分隔的CSV文件导入一个列表<列表< string>>,它实际上是一个数组。

class CSV 
{ 
    public List<List<string>> content = new List<List<string>>(); 
    private string path; 

    public CSV(string path) 
    { 
     this.path = path; 
    } 

    public void Load() 
    { 
     System.IO.StreamReader raw = new System.IO.StreamReader(path); 
     while (!raw.EndOfStream) 
     { 
      string[] tmp = raw.ReadLine().Split(","[0]); 
      content.Add(ArrayToList(tmp)); 
     } 

    } 

    private List<string> ArrayToList(string[] array) 
    { 
     List<string> array_out = new List<string>(); 
     for(int x = 0; x < array.Length; x++) 
     { 
      array_out.Add(array[x]); 
     } 
     return array_out; 
    } 
} 

下面是关于如何使用它的一个例子:

CSV csv = new CSV("C:\file.csv"); //Sets the filename to be used. Can be relative (".\file.csv") 
csv.Load(); //Loads the CSV file into the List<List<string>> 
System.Console.WriteLine(csv.content[row][column]); //Read a cell in the CSV array 

如果你必须使用一个字符串[] [],这里是转换列表<列表<字符串>>一种方法一个字符串[] []

public string[][] ListToArray(List<List<string>> list) 
    { 
     string[][] array_out = new string[list.Count][]; 
     for(int x=0; x<list.Count; x++) 
     { 
      for(int y=0; y<list[x].Count; y++) 
      { 
       array_out[x][y] = list[x][y]; 
      } 
     } 
     return array_out; 
    } 

希望这有助于!