unreal400
asked on
Load CSV into and array c#
I need to load a csv file with unknown number of rows and columns into a 2d array.
What is the best way to do this in c#
What is the best way to do this in c#
ASKER
The problem is we get these files in and they are not structured in a way that is easy to load. I have to transpose the entire file to a format that is capaible of loading into a database.
So if I read line by line I can't get the data I need. There is stuff in columns that should be in rows etc. I have no control of the way these files are created but I need to transpose them and load them. so I just want to put the whole thing into and array and write a loop to generate a properly formated file that I can just dts load.
Kelly
So if I read line by line I can't get the data I need. There is stuff in columns that should be in rows etc. I have no control of the way these files are created but I need to transpose them and load them. so I just want to put the whole thing into and array and write a loop to generate a properly formated file that I can just dts load.
Kelly
If you are working with c# 2005, then this will be a simple solution:
public string[][] ReadCSV(string filename)
{
List<string[]> tempList = new List<string[]>();
string line;
StreamReader reader = new StreamReader(filename);
while ((line = reader.ReadLine()) != null)
{
tempList.Add(line.Split(", "));
}
reader.Close();
return tempList.ToArray();
}
writting from my mind, maybe some bugs....
public string[][] ReadCSV(string filename)
{
List<string[]> tempList = new List<string[]>();
string line;
StreamReader reader = new StreamReader(filename);
while ((line = reader.ReadLine()) != null)
{
tempList.Add(line.Split(",
}
reader.Close();
return tempList.ToArray();
}
writting from my mind, maybe some bugs....
then just take that code .. read line by line and stuff it in an array or List<List<string>>
there are bugs there jaime .. it doesn't actually support CSV files :) the spec is a bit mroe complex than just splitting on , .. strings can be "" delimited (new lines and commas can appear in strings). Once you support this you also need to handle escaping of quotes in the strings.
I have done this to Excel spreadsheets. I put them into a DataSet, which is basically an array. Here is an example:
string strStockConnString="Driver ={Microsof t Excel Driver (*.xls)};DBQ=" + Server.MapPath("../") + "\\Temp.xls";
try
{
System.Data.Odbc.OdbcDataA dapter objStockDta = new System.Data.Odbc.OdbcDataA dapter("SE LECT * FROM [" + txtRange.Text + "]",strStockConnString);
DataSet ds = new DataSet();
objStockDta.Fill(ds);
}
txtRange.Text can be a Range defined by you, or a normal Excel Range ie: A1:Z50. You can define your own range by highlighting the entire area (both rows and columns) and changing it at the top left where you would see the column name (ie "A1"). You need to save the document if you define your own range, but either method is pretty effective.
string strStockConnString="Driver
try
{
System.Data.Odbc.OdbcDataA
DataSet ds = new DataSet();
objStockDta.Fill(ds);
}
txtRange.Text can be a Range defined by you, or a normal Excel Range ie: A1:Z50. You can define your own range by highlighting the entire area (both rows and columns) and changing it at the top left where you would see the column name (ie "A1"). You need to save the document if you define your own range, but either method is pretty effective.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
i'm trying out that solution Jaime I'll let you know if it works for what I need.
why are we rewriting code for such a common task here?
using the library I pointed you to ...
// open the file "data.csv" which is a CSV file with headers
using (CsvReader csv =
new CsvReader(new StreamReader(Filename), true))
{
int fieldCount = csv.FieldCount;
string[] headers = csv.GetFieldHeaders();
List<string[]> Data = new List<string>(); //use array list if you dont have 2.0
Data.Add(headers); //assuming you want the first row to contain header information
while (csv.ReadNextRecord())
{
string [] row = new string[fieldcount];
for (int i = 0; i < fieldCount; i++)
row[i] = csv[i];
Data.Add(row);
}
return Data.ToArray(); //returns string [][]
}
not only is this code simpler it also is very well tested and known to completely support the CSV spec.
buy .. don't build (especially when buying is free) :)
using the library I pointed you to ...
// open the file "data.csv" which is a CSV file with headers
using (CsvReader csv =
new CsvReader(new StreamReader(Filename), true))
{
int fieldCount = csv.FieldCount;
string[] headers = csv.GetFieldHeaders();
List<string[]> Data = new List<string>(); //use array list if you dont have 2.0
Data.Add(headers); //assuming you want the first row to contain header information
while (csv.ReadNextRecord())
{
string [] row = new string[fieldcount];
for (int i = 0; i < fieldCount; i++)
row[i] = csv[i];
Data.Add(row);
}
return Data.ToArray(); //returns string [][]
}
not only is this code simpler it also is very well tested and known to completely support the CSV spec.
buy .. don't build (especially when buying is free) :)
ASKER
jaime code worked I just had to rewrite a few chunks of it and removed your loop since I don't have quotation marks allowed in these files.
public string[][] ReadCSV(string filename)
{
List<string[]> tempList = new List<string[]>();
string line;
StreamReader reader = new StreamReader(filename);
while ((line = reader.ReadLine()) != null)
{
tempList.Add(SplitCSVLine( line));
}
reader.Close();
return tempList.ToArray();
}
public string[] SplitCSVLine(string line)
{
List<string> result = new List<string>();
result.AddRange(line.Split (new char[] { ',' }));
return result.ToArray();
}
public string[][] ReadCSV(string filename)
{
List<string[]> tempList = new List<string[]>();
string line;
StreamReader reader = new StreamReader(filename);
while ((line = reader.ReadLine()) != null)
{
tempList.Add(SplitCSVLine(
}
reader.Close();
return tempList.ToArray();
}
public string[] SplitCSVLine(string line)
{
List<string> result = new List<string>();
result.AddRange(line.Split
return result.ToArray();
}
why would you bother? the example I gave worked for any valid CSV and was less code ..
btw: why would you do this?
public string[] SplitCSVLine(string line)
{
List<string> result = new List<string>();
result.AddRange(line.Split (new char[] { ',' }));
return result.ToArray();
}
you add your string array to a List<string> just so you can convert them back to a string array?
try ..
public string[] SplitCSVLine(string line)
{
return line.Split(new char[] { ',' });
}
btw: why would you do this?
public string[] SplitCSVLine(string line)
{
List<string> result = new List<string>();
result.AddRange(line.Split
return result.ToArray();
}
you add your string array to a List<string> just so you can convert them back to a string array?
try ..
public string[] SplitCSVLine(string line)
{
return line.Split(new char[] { ',' });
}
I might ask why you need it in array as opposed to another structure (or reading line by line which will work much better for big files as you dont need to hold every item in memory (only the current one)). Either way this one in particular should be pretty easy to work with http://www.codeproject.com/cs/database/CsvReader.asp
Cheers,
Greg