user1384356
user1384356

Reputation: 7

Using linq spliting the text file and storing into the datatable

My requirement is I need to split a text file and store into a datatable. Refer the following code and column separator "|" and row separator "^":

var text = streamReader.ReadToEnd();
var lines = text.Split('^');
var rows = lines.Select(l => new {Line = l, Fields = l.Split('|')});
var colCount = rows.Max(r => r.Fields.Length);

var tblRegistration = new DataTable();
for (int i = 1; i <= colCount; i++)
{
    tblRegistration.Columns.Add("Column" + i, typeof (string));
}

When it is correct format it will work fine.

But end user may upload text file like

adfafdsafsdfsdfs^fsdf|sfsdf|sdfsfd|dfs...

in the first row there is only one column, but there should be four. In this case how to validate it?

Upvotes: 0

Views: 336

Answers (2)

Tim Schmelter
Tim Schmelter

Reputation: 460168

If your desired result is that you fill every column from left to the right it's easy:

foreach (var row in rows)
{
    var newRow = tblRegistration.Rows.Add();
    newRow.ItemArray = row.Fields;
}

So your example file would generate this DataTable:

Column1            Column2   Column3    Column4
adfafdsafsdfsdfs            
fsdf               sfsdf     sdfsfd     dfs

If you want to throw an exception:

foreach (var row in rows)
{
    if(row.Fields.Length != tblRegistration.Columns.Count)
        throw new Exception("Please upload the correct format");

    var newRow = tblRegistration.Rows.Add();
    newRow.ItemArray = row.Fields;
}

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1501163

It sounds like you should probably have something like:

// Call ToList to avoid splitting every time you access
var rows = lines.Select(l => new {Line = l, Fields = l.Split('|')}).ToList();

var expectedColumns = rows[0].Fields.Length;
if (rows.Any(row => row.Fields.Length != expectedColumns))
{
    // There's a broken row. Throw an exception or whatever...
}

That's assuming that all rows should have the same number of fields, of course.

If you want to show the broken row, you could change it to:

var firstBadRow = rows.FirstOrDefault(row => row.Fields.Length != expectedColumns));
if (firstBadRow != null)
{
    // Handle it however you want...
}

Upvotes: 3

Related Questions