Is there a way to go to the last line of a file in C #?

I have a read method that reads the date from the beginning of the file and then the date at the end of the file. The problem is that the file is huge and it takes a long time. Can I read the first line, ignore everything but the last, and then read the last line?

//Time consuming current method
int counter = 0;
DateTime begDate = new DateTime();
DateTime endDate = new DateTime();
while ((read = s.ReadLine()) != null)
{
    if (counter != 0) //skip first line
    {

        string[] Currentline = read.Split(comma);
        DateTime ThisBarsDate = DateTime.ParseExact(Currentline[1] + Currentline[2], "yyyyMMddHHmmss", new CultureInfo("en-US"));
        if (counter == 1) begDate = ThisBarsDate;

        endDate = ThisBarsDate; //will be correct at end of loop
    }
    counter++;
}
s.Close();

      

+2


source to share


6 answers


There is essentially no easy way to do this via the existing API. One option is to look for the end of the file and then start backward looking for the first new pair.

Here's a small example. This is not a very robust solution, but it provides the basic structure you are looking for.



public string GetLastLine(Stream stream, Encoding enc) {
  const int64 range = 100;
  var found = false;
  var index = stream.Length;
  var data = new byte[range];
  var builder = new StringBuilder();
  while ( true ) { 
    index = Math.Max(0, index -= range); 
    var count = stream.Read(data, 0, data.Length);
    if ( count == 0 ) {
      break;
    }
    var text = enc.GetString(data, 0, count);
    var newLineIndex = text.Index(Environment.NewLine);
    if ( newLineIndex >= 0 ) {
      builder.Insert(text.SubString(newLineIndex+Environment.NewLine.Length),0);
      break; 
    } else { 
      builder.Insert(text, 0);
    }
  }
  return builder.ToString();
}

      

+3


source


If you have a FileStream, you can use the Seek method to find an offset from the end of the file and start reading from there.

 var file = new FileStream(...);
 var reader = new StreamReader(file);
 long bytesToSkip =  ...number of bytes in last line...
 file.Seek( bytesToSkip, SeekOrigin.End );
 var endDate = reader.ReadToEnd();

      



Obviously this is not a complete solution, but it should give you enough to get started. Basically, you want to find the end of the file - this should skip all the blocks in the file except the last one, which it will have to read to get to the end, and then move back a few bytes. The number must be sufficient to cover the last line. If you know its exact length, that's even better. This is the example I showed. If not, skip enough to make sure you go back to the beginning of the last line and then start reading the lines and doing your transformation.

+3


source


Check FileStream.Seek()

with SeekOrigin

of End

.

+2


source


See this related stackoverflow question:

Get the last 10 lines of a very large text file

+2


source


As others have said, there is no good, easy, built-in way to do this. You may even have to keep a close eye on the end of the file and count backwards if there might be multibyte characters.

However, you can still significantly improve the situation. The problem with your current code is that it takes a while to parse each line, even though you only care about the first and last. Try this instead:

//Time consuming current method
DateTime begDate = new DateTime();
DateTime endDate = new DateTime();

s.ReadLine(); //skip first line - assume there is at least the header and the first record
string[] record = s.ReadLine().Split(comma);
begDate = DateTime.ParseExact(record[1] + record[2], "yyyyMMddHHmmss", new CultureInfo("en-US"));

string prev, read;
while ((read = s.ReadLine()) != null)
{
    prev = read;
}

record = prev.Split(comma);
endDate = DateTime.ParseExact(record[1] + record[2], "yyyyMMddHHmmss", new CultureInfo("en-US"));

      

Note that the loop almost doesn't work; it just copies the link. Also note that I was not showing the call .Close()

. It is of course you opened the file with the instruction using

to make sure the file is closed even if an exception is thrown. You opened the file with the instructions using

, right?

+2


source


Here is the code you can use to get the last line

StreamReader streamReader = new StreamReader("C:\\Text.txt");
ArrayList lines = new ArrayList();

string t =streamReader.ReadToEnd() ;

streamReader.Close();
Console.Write((t.Substring(t.LastIndexOf(System.Environment.NewLine))));
Console.ReadKey(); 

      

Hope it helps.

-3


source







All Articles