【问题标题】:C# Read a particular value from CSV file [duplicate]C#从CSV文件中读取特定值[重复]
【发布时间】:2015-02-07 08:03:31
【问题描述】:

我是 C# 的学习者。我想从 CSV 文件中读取特定值。我已经学会了通过浏览将 csv 文件放入数据表中。请查看以下代码(感谢 Surendra jha)和我的 CSV 文件格式。比如说,我想得到 'ID' = 90 的 'Volume' 是多少。

CSV 文件

ID:Volume:Name
100:5600:A
95:5000:B
90:4500:C
85:4000:D

获取所有值的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Data;              
namespace DVHConsolePrj
{
   class Program
     {
       static void Main(string[] args)
         {
             readCsvFileData();
          }
        static void readCsvFileData()
         {            
            string path = @"C:\IDVolumeName.txt";           
            StreamReader streamreader = new StreamReader(path);
            DataTable datatable = new DataTable();
            int rowcount = 0;
            string[] columnname = null;
            string[] streamdatavalue = null;
            while (!streamreader.EndOfStream)
            {
               string streamrowdata = streamreader.ReadLine().Trim();
                 if (streamrowdata.Length > 0) 
                    {
                       streamdatavalue = streamrowdata.Split(':'); 
                       if (rowcount == 0)
                       {
                          rowcount = 1;
                          columnname = streamdatavalue;
                          foreach (string csvheader in columnname)
                          {
                             DataColumn datacolumn = new DataColumn(csvheader.ToUpper(), typeof(string));
                             datacolumn.DefaultValue = string.Empty;
                             datatable.Columns.Add(datacolumn);
                           }
                        }
                        else
                        {
                          DataRow datarow = datatable.NewRow();
                          for (int i = 0; i < columnname.Length; i++)
                          {
                           datarow[columnname[i]] = streamdatavalue[i] == null ?             string.Empty : streamdatavalue[i].ToString();
                           }
                           datatable.Rows.Add(datarow);
                         }
                   }
          }
          streamreader.Close();
          streamreader.Dispose();                         
          foreach (DataRow dr in datatable.Rows)
          {
              string rowvalues = string.Empty;
              foreach (string csvcolumns in columnname)
              {
                  rowvalues += csvcolumns + "=" + dr[csvcolumns].ToString() + "    ";
               }
              Console.WriteLine(rowvalues);
            }
           Console.ReadLine();
           }              
        }
     }

【问题讨论】:

  • 在 google 中搜索如何使用 C# 读取 csv 文件。这里有一个例子! stackoverflow.com/questions/5282999/…。无论如何,我强烈建议您使用 OleDbConnection !
  • 可以使用DataTable.Select的方法进行过滤
  • 我以前从未见过带有: 分隔符的csv 文件。我认为CSV 代表逗号分隔值。
  • 感谢您的帮助......
  • 但是,我有一个小问题......使用下面的代码,我可以检索到 95 到 85 但不是 100?我很困惑。这是替换 'foreach (DataRow..' string myID; Console.Write("Enter ID:"); myID = Console.ReadLine(); var filtered = datatable.Select(String.Format("ID = { 0}", myID)); if (filtered.Length > 0) { var Volume1 = filters[0]["VOLUME"]; Console.WriteLine("Volume is :{0}",Volume1); } Console.ReadLine ();

标签: c# csv


【解决方案1】:

不要在DataTable中手动解析文件,然后做一些Linq,直接在上面使用Linq,使用this library

它工作得很好,对大文件非常有效。

例如。

1)在你的项目中添加nuget包,下面一行就可以使用了:

using LINQtoCSV;

2) 定义旧数据的类

public class IdVolumeNameRow
{
    [CsvColumn(FieldIndex = 1)]
    public string ID { get; set; }

    [CsvColumn(FieldIndex = 2)]
    public decimal Volume { get; set; }

    [CsvColumn(FieldIndex = 3)]
    public string Name{ get; set; }
}

3) 并搜索值

    var csvAttributes = new CsvFileDescription
    {
        SeparatorChar = ':',
        FirstLineHasColumnNames = true
    };

    var cc = new CsvContext();

    var volume = cc.Read<IdVolumeNameRow>(@"C:\IDVolumeName.txt", csvAttributes)
            .Where(i => i.ID == "90")
            .Select(i => i.Volume)
            .FirstOrDefault();

【讨论】:

    【解决方案2】:
    public DataTable CSVToDataTable(string filename, string separator)
    {
        try
        {
            FileInfo file = new FileInfo(filename);
    
            OleDbConnection con = 
                new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=\"" +
                file.DirectoryName + "\";
                Extended Properties='text;HDR=Yes;FMT=Delimited(" + separator + ")';")
    
            OleDbCommand cmd = new OleDbCommand(string.Format
                                      ("SELECT * FROM [{0}]", file.Name), con);
    
            con.Open();
    
            DataTable tbl = new DataTable();
    
            using (OleDbDataAdapter adp = new OleDbDataAdapter(cmd))
            {
                tbl = new DataTable("MyTable");
                adp.Fill(tbl);        
            }
    
            return tbl;
         }
         catch(Exception ex)
         {
             throw ex;
         }
         finally()
         {
            con.Close();
         }  
    } 
    

    你可以试试这个代码,它是动态构建的,可能存在一些小错误。检查 OleDbConnection。当您返回 DataTable 时,您可以使用 LINQ 在表中进行搜索。

    var results = from myRow in myDataTable.AsEnumerable()
    where myRow.Field<int>("ID") == 90
    select myRow;
    

    这里可以取 ID=90 的行!

    【讨论】:

    • 这如何回答他的问题?
    • 简单,我将 CSV 文件返回到 DataTable 中。之后,我使用 LINQ 来查找正确的值。
    • 他的问题明确是如何获取 ID 90 的卷。您的回答丝毫没有涵盖它。
    • @Serv 现在你可以检查它了。我写得很明确,他可以为每个值对 dataTable 进行 LINQ。
    • 现在更像了。
    【解决方案3】:

    要过滤 DataTable,您可以使用 DataTable.Select 这样的方法

    var filtered = dataTable.Select("ID = '90'");
    

    filtered 上面是适合该条件的数据行数组,因此要从第一个过滤行中获取值,您可以使用类似

    if(filtered.Length>0){
        var Volume = filtered[0]["VOLUME"];
    }
    

    【讨论】:

    • 字符串我的ID; Console.Write("输入ID:"); myID = Console.ReadLine(); var filters = datatable.Select(String.Format("ID = {0}", myID)); if (filtered.Length > 0) { var Volume1 = filtered[0]["VOLUME"]; Console.WriteLine("音量为:{0}",Volume1); } Console.ReadLine();
    • 谢谢.. 但是,我有一个小问题.... 使用下面的代码,我可以检索 95 到 85 但不是 100?我很困惑。
    • @kmothpur,尝试将字符串格式更改为String.Format("ID = '{0}'", myID)
    • 我确实只使用了那个 String.Format 。我已经在评论中上传了代码.....
    • @kmothpur in string.Format 来自您的评论 - 使用简单的占位符:{0},在我的评论中:'{ 0}',我的意思是占位符周围的引号
    猜你喜欢
    • 2021-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-05
    • 1970-01-01
    相关资源
    最近更新 更多