Reputation: 300
I am fairly new to C# and I've been wrecking my head with a problem. I need to read one particular line/position from a CSV file (2nd line, 4th column), which ALWAYS hold the data I expect.
(If you're curious: this CSV file is a report and the first 3 lines are a header. The field in question holds a date)
Here is what I (sort of) started with after doing some research (and with my n00b C# skills):
dt = new DataTable();
string[] csvRows = System.IO.File.ReadAllLines(origFilePath);
dt.Columns.Add(csvRows[0]);
for (int x = 1; x < 2; x++)
{
dt.Rows.Add(csvRows[x]);
}
dt.Rows[0][0].ToString(); // must modify [0][0]
Thing is, the file can be quite big, so I don't think I need to read the entire file and setting it into a table object for then retrieving that value.
I'm sure there must be a better way?!
Can someone please advise? Thank you in advance for your help.
Regards, P.
Upvotes: 0
Views: 3928
Reputation: 41
Read line from CSV file, go directly to 15th position and get the value. Refer below c# code
namespace DBCreateTags
{
class Program
{
static void Main(string[] args)
{
using (var reader = new StreamReader(@"T:\test.csv"))
{
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
var values = line.Split(',')[15];
}
}
}
}
}
Upvotes: 0
Reputation: 5757
One-liner:
var myValue = System.IO.File.ReadLines(origFilePath).Skip(1).First().Split(',')[3];
I'm sure it's not the optimal way (I not even tested), but should do the trick.
Don't forget to import the Linq namespace (using System.Linq;
).
Upvotes: 2
Reputation: 34421
You can use oledb to read csv without opening. You can modify SQL statement to retrieve only column you need.
public class CSVReader
{
public DataSet ReadCSVFile(string fullPath, bool headerRow)
{
string path = fullPath.Substring(0, fullPath.LastIndexOf("\\") + 1);
string filename = fullPath.Substring(fullPath.LastIndexOf("\\") + 1);
DataSet ds = new DataSet();
try
{
if (File.Exists(fullPath))
{
string ConStr = string.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0}" + ";Extended Properties=\"Text;HDR={1};FMT=Delimited\\\"", path, headerRow ? "Yes" : "No");
string SQL = string.Format("SELECT * FROM {0}", filename);
OleDbDataAdapter adapter = new OleDbDataAdapter(SQL, ConStr);
adapter.Fill(ds, "TextFile");
ds.Tables[0].TableName = "Table1";
}
foreach (DataColumn col in ds.Tables["Table1"].Columns)
{
col.ColumnName = col.ColumnName.Replace(" ", "_");
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
return ds;
}
}
Upvotes: 0
Reputation: 2877
You're looking for a lazy method to get what you need. Lazy means avoiding reading the entire file to get the right line.
using (FileStream fs = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (BufferedStream bs = new BufferedStream(fs))
using (StreamReader sr = new StreamReader(bs))
{
var i = 0;
string line;
while ((line = sr.ReadLine()) != null)
{
if (i == 4) //4th position = 5th line (3 header lines plus 2 data lines)
{
return line.split(',')[3];
}
i++;
}
}
Code is partially ripped from here: Reading large text files with streams in C#
Alternatively, you can do:
var i = 0;
foreach (string line in File.ReadLines(filepath))
{
if (i == 4)
{
return line.split(',')[3];
}
i++;
}
Upvotes: 1