5

I know how to do this via streamreader and read to the end of line, but was curious if there was a fancier way of going it (for the sake of learing).

filename: blah.csv

File layout is simple:

"Some234234 ", 234
"blahblha234234 ", 2322

I want to load this into a dictionary (the second part should be a int, but I will parse later in case of errors).

Can you do this via linq somehow?

asked Dec 10, 2009 at 20:43
0

7 Answers 7

5

You should use the TextFieldParser class in Microsoft.VisualBasic.dll. (There's nothing wrong with using it in C#.

Remember that CSV is a much more complicated file format than you think; both quotes and newlines can be escaped.

answered Dec 10, 2009 at 20:50
1
  • Very true, and I have used it many times this way for complex csv's or csv's with unpredictable contents. But this is only necessary if you expect a complex file. In some cases it's a very simple file, for example all integer values. Commented Dec 29, 2013 at 1:36
4

CSV can be a lot more complicated than it appears at first. Here is an excellent library for reading CSV files.

http://www.codeproject.com/KB/database/CsvReader.aspx

answered Dec 10, 2009 at 21:35
1
  • 2
    I agree with this and with SLaks's reply. The most effective way to solve any problem is to use a solution that already exists. CSV seems to be one of those features that's just simple enough for people to re-invent on a whim, but still complex enough for most of them to make a mess out of. Commented Dec 10, 2009 at 21:43
3

Untested, but:

static IEnumerable<string> ReadLines(string path) {
 using (var file = File.OpenText(path)) {
 string line;
 while ((line = file.ReadLine()) != null) {
 yield return line;
 }
 }
}
var data = (from line in ReadLines(path)
 select line.Split(','))
 .ToDictionary(
 arr => arr[0].Trim('"', ' '),
 arr => int.Parse(arr[1].Trim()));
answered Dec 10, 2009 at 20:50
1
  • 2
    This will not handle escaped CSV files. Even if the CSV files aren't escaped right now, they might be in the future. Commented Dec 10, 2009 at 20:55
2
foreach (string s in File.ReadAllLines(filename)) {
 var vals = s.Split(',')
 dictionary[vals[0]] = vals[1];
}

No LINQ but this is simple really. Doesn't handle embedded ',''s in the first value though.

answered Dec 10, 2009 at 20:51
2
  • This will not handle escaped CSV files. Even if the CSV files aren't escaped right now, they might be in the future. Commented Dec 10, 2009 at 20:56
  • He obviously doesn't care about things like this as he put it "for the sake of learing." CSV isn't even a standardized format, his CSV might not allow escaping. Commented Dec 10, 2009 at 20:59
2
 string[] file = File.ReadAllLines(@"C:\temp\dictionary.txt");
 Dictionary<string, string> b = (from p in file
 let x = p.Split(',')
 select x).ToDictionary(a => a[0], a => a[1]);
answered Dec 10, 2009 at 20:54
1
  • This will not handle escaped CSV files. Even if the CSV files aren't escaped right now, they might be in the future. Commented Dec 10, 2009 at 20:56
1

You could use File.ReadAllLines(), Select() and ToDictionary() to do this:

var d = File.ReadAllLines(file).Select( l => {
 var split = l.Split(',');
 return new { Key = split[0], Value = split[1] };
} ).ToDictionary( p => p.Key, p => p.Value );

But there are obvious problems here with respect to error handling and robustness, and as you add those, it gets worse and worse. I don't feel there's a particular good reason prefer LINQ or its extension methods here, as it isn't buying you much. The straightforward ways, posted already, are much cleaner.

EDIT: Sid's answer, for example, contains essentially the same code, but written in a much, much cleaner form by avoiding all this "fancy" junk.

answered Dec 10, 2009 at 20:55
1

This might be overkill in your simple scenario, but for CSV to strongly typed collection conversion, I usually use FileHelpers.

It's a great tool to have in the tool box.

answered Dec 10, 2009 at 22:27
2
  • How can i use filehelpers to load CSV into the pregenereterd OR classes that can be used in LINQ2SQL instead of creating new class and assigning each damn field to it? I have a old school table with 300+ columns.. yay Commented Oct 10, 2012 at 10:43
  • I don't know your "pregenerated OR classes", but if minimizing code and violate SRP is okay, I guess you could use the same types and add the appropriate FileHelpers attributes. Personally, I'd separate the concerns, and map from the FileHelper types to the L2S types with AutoMapper. Commented Oct 10, 2012 at 11:41

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.