Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/262.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用C读取CSV文件#_C#_Csv - Fatal编程技术网

C# 使用C读取CSV文件#

C# 使用C读取CSV文件#,c#,csv,C#,Csv,我正在编写一个简单的导入应用程序,需要读取一个CSV文件,在数据网格中显示结果,并在另一个网格中显示CSV文件的损坏行。例如,在另一个栅格中显示小于5个值的线。我试着这样做: StreamReader sr = new StreamReader(FilePath); importingData = new Account(); string line; string[] row = new string [5]; while ((line = sr.ReadLine()) != null) {

我正在编写一个简单的导入应用程序,需要读取一个CSV文件,在数据网格中显示结果,并在另一个网格中显示CSV文件的损坏行。例如,在另一个栅格中显示小于5个值的线。我试着这样做:

StreamReader sr = new StreamReader(FilePath);
importingData = new Account();
string line;
string[] row = new string [5];
while ((line = sr.ReadLine()) != null)
{
    row = line.Split(',');

    importingData.Add(new Transaction
    {
        Date = DateTime.Parse(row[0]),
        Reference = row[1],
        Description = row[2],
        Amount = decimal.Parse(row[3]),
        Category = (Category)Enum.Parse(typeof(Category), row[4])
    });
}

但在这种情况下,对阵列进行操作非常困难。有没有更好的方法来分割这些值?

不要重新发明轮子。利用.NET BCL中已有的功能

  • 添加对
    Microsoft.VisualBasic
    的引用(是的,它说的是VisualBasic,但它在C#中也可以工作-记住,最后它只是IL)
  • 使用Microsoft.VisualBasic.FileIO.TextFieldParser类来解析CSV文件
以下是示例代码:

using (TextFieldParser parser = new TextFieldParser(@"c:\temp\test.csv"))
{
    parser.TextFieldType = FieldType.Delimited;
    parser.SetDelimiters(",");
    while (!parser.EndOfData) 
    {
        //Processing row
        string[] fields = parser.ReadFields();
        foreach (string field in fields) 
        {
            //TODO: Process field
        }
    }
}
在我的C#项目中,它对我非常有用

以下是更多的链接/信息:

    • CSV可以很快变得复杂。

      使用可靠且经过良好测试的工具:
      文件助手:

      FileHelpers是一个免费且易于使用的.NET库,用于从文件、字符串或流中的固定长度或分隔记录导入/导出数据。
      根据我的经验,有许多不同的csv格式。特别是它们如何处理字段中引号和分隔符的转义

      这些是我遇到的变体:

      • 引用和双引号(excel),即15“->字段1,“15”“”,字段3
      • 除非由于其他原因引用字段,否则不会更改引号。例如,15“->字段1,15”,字段3
      • 引号用\.即15“->字段1、“15\”和字段3转义
      • 引号完全没有更改(这并不总是能够正确解析)
      • 带引号的分隔符(excel)。即a,b->field1,“a,b”,field3
      • 分隔符用\.即a,b->field1,a \,b,field3转义
      我尝试过许多现有的csv解析器,但没有一个能够处理我遇到的变体。从文档中也很难找到解析器支持哪些转义变体

      在我的项目中,我现在使用VB TextFieldParser或自定义拆分器。

      我在这里使用:

      上次我在寻找类似的东西时,我发现它是对此的一个答案。

      我推荐

      PS:关于其他更高投票率的答案,我很抱歉,但添加了对
      Microsoft的引用。VisualBasic
      是:

      • 丑陋的
      • 不是跨平台的,因为它在.NETCore/.NET5中不可用(而且Mono从来没有很好地支持Visual Basic,所以它可能有缺陷)

      当您不想重新发明程序时,有时使用库是很酷的,但在这种情况下,与使用库相比,您可以用更少的代码行和更易于阅读的方式完成同样的工作。 这里有一种不同的方法,我觉得很容易使用

    • 在本例中,我使用StreamReader读取文件
    • Regex从每行检测分隔符
    • 用于收集从索引0到n的列的数组


    • 要完成前面的回答,可能需要从CSV文件中收集对象,通过
      TextFieldParser
      string.Split
      方法进行解析,然后通过反射将每一行转换为一个对象。显然,首先需要定义一个与CSV文件中的行匹配的类

      我使用了Michael Kropat在此处找到的简单CSV序列化程序: 并重用他的方法来获取所需类的字段和属性

      我使用以下方法反序列化我的CSV文件:

      public static IEnumerable<T> ReadCsvFileTextFieldParser<T>(string fileFullPath, string delimiter = ";") where T : new()
      {
          if (!File.Exists(fileFullPath))
          {
              return null;
          }
      
          var list = new List<T>();
          var csvFields = GetAllFieldOfClass<T>();
          var fieldDict = new Dictionary<int, MemberInfo>();
      
          using (TextFieldParser parser = new TextFieldParser(fileFullPath))
          {
              parser.SetDelimiters(delimiter);
      
              bool headerParsed = false;
      
              while (!parser.EndOfData)
              {
                  //Processing row
                  string[] rowFields = parser.ReadFields();
                  if (!headerParsed)
                  {
                      for (int i = 0; i < rowFields.Length; i++)
                      {
                          // First row shall be the header!
                          var csvField = csvFields.Where(f => f.Name == rowFields[i]).FirstOrDefault();
                          if (csvField != null)
                          {
                              fieldDict.Add(i, csvField);
                          }
                      }
                      headerParsed = true;
                  }
                  else
                  {
                      T newObj = new T();
                      for (int i = 0; i < rowFields.Length; i++)
                      {
                          var csvFied = fieldDict[i];
                          var record = rowFields[i];
      
                          if (csvFied is FieldInfo)
                          {
                              ((FieldInfo)csvFied).SetValue(newObj, record);
                          }
                          else if (csvFied is PropertyInfo)
                          {
                              var pi = (PropertyInfo)csvFied;
                              pi.SetValue(newObj, Convert.ChangeType(record, pi.PropertyType), null);
                          }
                          else
                          {
                              throw new Exception("Unhandled case.");
                          }
                      }
                      if (newObj != null)
                      {
                          list.Add(newObj);
                      }
                  }
              }
          }
          return list;
      }
      
      public static IEnumerable<MemberInfo> GetAllFieldOfClass<T>()
      {
          return
              from mi in typeof(T).GetMembers(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static)
              where new[] { MemberTypes.Field, MemberTypes.Property }.Contains(mi.MemberType)
              let orderAttr = (ColumnOrderAttribute)Attribute.GetCustomAttribute(mi, typeof(ColumnOrderAttribute))
              orderby orderAttr == null ? int.MaxValue : orderAttr.Order, mi.Name
              select mi;            
      }
      
      公共静态IEnumerable ReadCsvFileTextFieldParser(字符串fileFullPath,字符串分隔符=“;”),其中T:new()
      {
      如果(!File.Exists(fileFullPath))
      {
      返回null;
      }
      var list=新列表();
      var csvFields=GetAllFieldOfClass();
      var fieldDict=新字典();
      使用(TextFieldParser=newtextfieldparser(fileFullPath))
      {
      SetDelimiters(分隔符);
      bool headerParsed=假;
      而(!parser.EndOfData)
      {
      //处理行
      string[]rowFields=parser.ReadFields();
      如果(!headerParsed)
      {
      for(int i=0;if.Name==rowFields[i]).FirstOrDefault();
      if(csvField!=null)
      {
      fieldDict.Add(i,csvField);
      }
      }
      headerParsed=真;
      }
      其他的
      {
      T newObj=新的T();
      for(int i=0;ipublic static IEnumerable<T> ReadCsvFileTextFieldParser<T>(string fileFullPath, string delimiter = ";") where T : new()
      {
          if (!File.Exists(fileFullPath))
          {
              return null;
          }
      
          var list = new List<T>();
          var csvFields = GetAllFieldOfClass<T>();
          var fieldDict = new Dictionary<int, MemberInfo>();
      
          using (TextFieldParser parser = new TextFieldParser(fileFullPath))
          {
              parser.SetDelimiters(delimiter);
      
              bool headerParsed = false;
      
              while (!parser.EndOfData)
              {
                  //Processing row
                  string[] rowFields = parser.ReadFields();
                  if (!headerParsed)
                  {
                      for (int i = 0; i < rowFields.Length; i++)
                      {
                          // First row shall be the header!
                          var csvField = csvFields.Where(f => f.Name == rowFields[i]).FirstOrDefault();
                          if (csvField != null)
                          {
                              fieldDict.Add(i, csvField);
                          }
                      }
                      headerParsed = true;
                  }
                  else
                  {
                      T newObj = new T();
                      for (int i = 0; i < rowFields.Length; i++)
                      {
                          var csvFied = fieldDict[i];
                          var record = rowFields[i];
      
                          if (csvFied is FieldInfo)
                          {
                              ((FieldInfo)csvFied).SetValue(newObj, record);
                          }
                          else if (csvFied is PropertyInfo)
                          {
                              var pi = (PropertyInfo)csvFied;
                              pi.SetValue(newObj, Convert.ChangeType(record, pi.PropertyType), null);
                          }
                          else
                          {
                              throw new Exception("Unhandled case.");
                          }
                      }
                      if (newObj != null)
                      {
                          list.Add(newObj);
                      }
                  }
              }
          }
          return list;
      }
      
      public static IEnumerable<MemberInfo> GetAllFieldOfClass<T>()
      {
          return
              from mi in typeof(T).GetMembers(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static)
              where new[] { MemberTypes.Field, MemberTypes.Property }.Contains(mi.MemberType)
              let orderAttr = (ColumnOrderAttribute)Attribute.GetCustomAttribute(mi, typeof(ColumnOrderAttribute))
              orderby orderAttr == null ? int.MaxValue : orderAttr.Order, mi.Name
              select mi;            
      }
      
      using Microsoft.VisualBasic.FileIO;
      
      Csv csv = new Csv("\t");//delimiter symbol
      
      csv.FileOpen("c:\\file1.csv");
      
      var row1Cell6Value = csv.Rows[0][5];
      
      csv.AddRow("asdf","asdffffff","5")
      
      csv.FileSave("c:\\file2.csv");
      
      private static DataTable ConvertCSVtoDataTable(string strFilePath)
              {
                  DataTable dt = new DataTable();
                  using (StreamReader sr = new StreamReader(strFilePath))
                  {
                      string[] headers = sr.ReadLine().Split(',');
                      foreach (string header in headers)
                      {
                          dt.Columns.Add(header);
                      }
                      while (!sr.EndOfStream)
                      {
                          string[] rows = sr.ReadLine().Split(',');
                          DataRow dr = dt.NewRow();
                          for (int i = 0; i < headers.Length; i++)
                          {
                              dr[i] = rows[i];
                          }
                          dt.Rows.Add(dr);
                      }
      
                  }
      
                  return dt;
              }
      
              private static void WriteToDb(DataTable dt)
              {
                  string connectionString =
                      "Data Source=localhost;" +
                      "Initial Catalog=Northwind;" +
                      "Integrated Security=SSPI;";
      
                  using (SqlConnection con = new SqlConnection(connectionString))
                      {
                          using (SqlCommand cmd = new SqlCommand("spInsertTest", con))
                          {
                              cmd.CommandType = CommandType.StoredProcedure;
      
                              cmd.Parameters.Add("@policyID", SqlDbType.Int).Value = 12;
                              cmd.Parameters.Add("@statecode", SqlDbType.VarChar).Value = "blagh2";
                              cmd.Parameters.Add("@county", SqlDbType.VarChar).Value = "blagh3";
      
                              con.Open();
                              cmd.ExecuteNonQuery();
                          }
                      }
      
               }
      
      Id, Name
      1, Tom
      2, Mark
      
      using (var reader = new ChoCSVReader("test.csv").WithFirstLineHeader())
      {
         foreach (dynamic item in reader)
         {
            Console.WriteLine(item.Id);
            Console.WriteLine(item.Name);
         }
      }
      
      public class Employee
      {
         public int Id { get; set; }
         public string Name { get; set; }
      }
      
      using (var reader = new ChoCSVReader<Employee>("test.csv").WithFirstLineHeader())
      {
         foreach (var item in reader)
         {
            Console.WriteLine(item.Id);
            Console.WriteLine(item.Name);
         }
      }
      
      public class csvExampleClass
      {
          public string Id { get; set; }
          public string Firstname { get; set; }
          public string Lastname { get; set; }
      }
      
      var items = DeserializeCsvFile<List<csvExampleClass>>( csvText );
      
      public static List<T> DeserializeCsvFile<T>(string text)
      {
          CsvReader csv = new CsvReader( new StringReader( text ) );
          csv.Configuration.Delimiter = ",";
          csv.Configuration.HeaderValidated = null;
          csv.Configuration.MissingFieldFound = null;
          return (List<T>)csv.GetRecords<T>();
      }
      
              static List<List<string>> ParseCsv(string csv) {
                  var parsedCsv = new List<List<string>>();
                  var row = new List<string>();
                  string field = "";
                  bool inQuotedField = false;
      
                  for (int i = 0; i < csv.Length; i++) {
                      char current = csv[i];
                      char next = i == csv.Length - 1 ? ' ' : csv[i + 1];
      
                      // if current character is not a quote or comma or carriage return or newline (or not a quote and currently in an a quoted field), just add the character to the current field text
                      if ((current != '"' && current != ',' && current != '\r' && current != '\n') || (current != '"' && inQuotedField)) {
                          field += current;
                      } else if (current == ' ' || current == '\t') {
                          continue; // ignore whitespace outside a quoted field
                      } else if (current == '"') {
                          if (inQuotedField && next == '"') { // quote is escaping a quote within a quoted field
                              i++; // skip escaping quote
                              field += current;
                          } else if (inQuotedField) { // quote signifies the end of a quoted field
                              row.Add(field);
                              if (next == ',') {
                                  i++; // skip the comma separator since we've already found the end of the field
                              }
                              field = "";
                              inQuotedField = false;
                          } else { // quote signifies the beginning of a quoted field
                              inQuotedField = true; 
                          }
                      } else if (current == ',') { //
                          row.Add(field);
                          field = "";
                      } else if (current == '\n') {
                          row.Add(field);
                          parsedCsv.Add(new List<string>(row));
                          field = "";
                          row.Clear();
                      }
                  }
      
                  return parsedCsv;
              }