AndreasPettersson
AndreasPettersson

Reputation: 117

Read latest line from CSV file

I have a CSV file that I need to read all values from. But only from the last row which is newest. But I can't figure it out how to do it.

Im using streamreader now but that loops through the whole CSV file which can be very big.

I need to read two diffrent csv files(headers are the same but on diffrent location).

But how can I edit this code to only read from the last row? I have searched around but could not find anything that are the same as mine.

So this is how I been doing right now:

using (var reader = new StreamReader(path))
            {
                var headerLine = reader.ReadLine();
                var headerValues = headerLine.Split(',');
                var serialNumber = headerValues[66];

                while (!reader.EndOfStream)
                {
                    var line = reader.ReadLine();
                    var values = line.Split(',');

                    if (values[0] != "Index")
                    {
                        var analyseReport = new AnalyseReport();
                        analyseReport.SerialNumber = serialNumber;

                        foreach (var item in headerValues)
                        {
                            var headerName = item.Trim();
                            var index = Array.IndexOf(headerValues, item);

                            switch (headerName)
                            {
                                case "Index":
                                    analyseReport.Index = Convert.ToInt32(values[index].Trim());
                                    break;

                                case "Time":
                                    analyseReport.TimeStamp = Convert.ToDateTime(values[index].Trim());
                                    break;

                                case "Reading No":
                                    analyseReport.ReadingNo = Convert.ToInt32(values[index].Trim());
                                    break;
                                case "Duration":
                                    analyseReport.Duration = values[index].Trim();
                                    break;

                                case "Type":
                                    analyseReport.Type = values[index].Trim();
                                    break;

                                case "Units":
                                    analyseReport.Units = values[index].Trim();
                                    break;

                                default:
                                    break;
                            }
                        }

                        analyseReportList.Add(analyseReport);

                    }
                }
                return analyseReportList;
            }

Upvotes: 1

Views: 3602

Answers (2)

Paul Kertscher
Paul Kertscher

Reputation: 9713

If you don't have fixed length lines, but can determine an upper limit of the length of your lines, you could use a heuristic to make reading the last line way more efficient.

Basically what to do is to move the current position of the file stream to n bytes from the end and then read until you've reached the last line.

private string ReadLastLine(string fileName, int maximumLineLength)
{
    string lastLine = string.Empty;

    using(Stream s = File.OpenRead(path))
    {
        s.Seek(-maximumLineLength, SeekOrigin.End);

        using(StreamReader sr = new StreamReader(s))
        {
            string line;

            while((line = sr.ReadLine()) != null)
            {
                lastLine = line;
            }
        }
    }

    return lastLine;
}

For a 1.8 MB CSV it's about 100-200 times faster than the File.ReadLines method. Anyway, at the cost of a way more complicated code.

Remarks: While you could use this method to optimize reading the last line, if it is really the bottleneck, please use the way clearer and cleaner version of Tim Schmelter, if at any rate possible. Please remember the second rule of optimization: "Don't do it, yet."

Futhermore, to determine the maximum length of your lines, you have to be careful and consider the character encoding. Rather over- than under-estimate the line length.

Upvotes: 3

Tim Schmelter
Tim Schmelter

Reputation: 460138

You could use File.ReadLines(path).Last():

string headerLine = File.ReadLines(path).First();
string lastLine = File.ReadLines(path).Last();
// ... (no loop)

These are LINQ methods so you need to add using System.Linq;.

Upvotes: 2

Related Questions