3

I am a learner in C#. I want to read a particular value from the CSV file. I have learned the getting the csv file into a datatable through browsing. Please see the following code (Thanks to surendra jha) and my CSV file format. Say, I want to get what is the 'Volume' for 'ID' = 90.

CSV file

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

Code for getting all the values:

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();
           }              
        }
     }
shankar.parshimoni
  • 1,289
  • 5
  • 22
  • 42
kmothpur
  • 131
  • 1
  • 2
  • Search in google how to read csv file with C#. Here an example ! http://stackoverflow.com/questions/5282999/reading-csv-file-and-storing-values-into-an-array. Anyway I strongly advice you to use OleDbConnection ! – mybirthname Dec 09 '14 at 12:21
  • you can use [DataTable.Select](http://msdn.microsoft.com/en-us/library/det4aw50(v=vs.110).aspx) method for filtering – Grundy Dec 09 '14 at 12:30
  • I have never seen a [tag:csv] file with `:` for delimiters before. I thought `CSV` stands for comma separated values. – John Alexiou Dec 09 '14 at 13:33
  • But, I have a small probs.... Using the following code, I can retrieve 95 to 85 but not 100? I am puzzled. Here is the code which replaces '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 = filtered[0]["VOLUME"]; Console.WriteLine("Volume is :{0}",Volume1); } Console.ReadLine(); – kmothpur Dec 09 '14 at 15:06

3 Answers3

2

Instead of parsing the file manually in a DataTable, then doing some Linq, use Linq directly on it, using this library.

It works pretty well and is very efficient with big files.

For instance.

1) Add nuget package in your project, and the following line to be able to use it:

using LINQtoCSV;

2) define the class that olds the data

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) and search for the value

    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();
Askolein
  • 3,250
  • 3
  • 28
  • 40
1
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();
     }  
} 

You can try this code, it is build on the fly, it is possible little errors to exist. Check OleDbConnection. When you return the DataTable you can search in the table using LINQ.

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

Here you can take the row with ID=90 !

mybirthname
  • 17,949
  • 3
  • 31
  • 55
0

For filtering DataTable you can use DataTable.Select method like this

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

filtered above is array of datarow that suitable for the condition, so for get value from first filtered row you can use something like

if(filtered.Length>0){
    var Volume = filtered[0]["VOLUME"];
}
Grundy
  • 13,356
  • 3
  • 35
  • 55
  • string myID; Console.Write("Enter ID:"); myID = Console.ReadLine(); var filtered = datatable.Select(String.Format("ID = {0}", myID)); if (filtered.Length > 0) { var Volume1 = filtered[0]["VOLUME"]; Console.WriteLine("Volume is :{0}",Volume1); } Console.ReadLine(); – kmothpur Dec 09 '14 at 15:10
  • Thanks.. But, I have a small probs.... Using the following code, I can retrieve 95 to 85 but not 100? I am puzzled. – kmothpur Dec 09 '14 at 15:11
  • @kmothpur, try change string format to `String.Format("ID = '{0}'", myID)` – Grundy Dec 09 '14 at 15:25
  • I did actually used that String.Format only. I have uploaded the code in the comment..... – kmothpur Dec 09 '14 at 15:37
  • @kmothpur in _string.Format_ from your comment - used simple place holder: _{0}_, in my comment: _'{0}'_, i mean quotes around placeholder – Grundy Dec 09 '14 at 15:51
  • Sorry. Noted now and it works now.....Excellent... :-) – kmothpur Dec 09 '14 at 16:24