有没有办法跳转到C#中文件的最后一行?

时间:2009-09-23 02:23:09

标签: c#

我有一个读取文件方法,它从文件的开头读取日期,然后读取文件末尾的日期。问题是文件很大,需要很长时间。有没有办法我可以读取第一行,忽略除最后一行之外的所有行,然后读取最后一行?

//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();

6 个答案:

答案 0 :(得分:3)

如果你有一个FileStream,你可以使用Seek方法寻找文件末尾的偏移量并从那里开始阅读。

 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();

显然,这不是一个完整的解决方案,但它应该足以让你开始。本质上,你想要寻找到文件的末尾 - 这应该跳过文件中除了最后一个之外的所有块,它必须读取才能到达末尾,然后向后导航一些字节。该数字应足以覆盖最后一行。如果你知道它的确切长度,那就更好了。这是我展示的例子。如果没有,请跳过,以确保您已经回到最后一行的开头,然后开始阅读行并进行转换。

答案 1 :(得分:3)

通过现有的API没有固有的简单方法。但是,一种选择是寻找文件的末尾,然后开始向后寻找第一个新的线对。

这是一个快速示例。它不是一个非常强大的解决方案,但它提供了您正在寻找的基本框架。

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();
}

答案 2 :(得分:2)

使用SeekOrigin的{​​{1}}查看FileStream.Seek()

答案 3 :(得分:2)

请参阅此相关的stackoverflow问题:

Get the last 10 lines of a very large text file

答案 4 :(得分:2)

正如其他人所说,没有好的,简单的,内置的方法来做到这一点。您甚至可能需要小心寻找文件的末尾并向后计数,以防可能存在多字节字符。

然而,你仍然可以显着改善。您当前代码的问题在于,它需要时间来解析每个行,即使您只关心第一个和最后一个。试试这个:

//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"));

请注意,循环几乎不起作用;它只是复制一个参考。另请注意,我没有显示.Close()电话。这是因为您使用using语句打开文件以确保文件已关闭,即使抛出异常也是如此。您确实使用using语句打开了文件,对吗?

答案 5 :(得分:-3)

以下是您可以用来获取最后一行的代码

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(); 

希望这会有所帮助。