C# 读取文本文件的最后一行
我需要知道如何读取文本文件的最后一行。我需要找到该行,然后将其处理到SQL数据库中。。。我一直在阅读和浏览网页,但我正在努力找到正确的方法来做到这一点。即:C# 读取文本文件的最后一行,c#,C#,我需要知道如何读取文本文件的最后一行。我需要找到该行,然后将其处理到SQL数据库中。。。我一直在阅读和浏览网页,但我正在努力找到正确的方法来做到这一点。即: 查找文件的最后一行 处理文件的最后一行 我希望这是有意义的。有两种方法:简单而低效,或者极其复杂但高效。复杂的版本采用合理的编码 除非您的文件太大,以至于您真的负担不起全部阅读,否则我只会使用: var lastLine = File.ReadLines("file.txt").Last(); 请注意,这使用的是,而不是。如果使用.NET
我希望这是有意义的。有两种方法:简单而低效,或者极其复杂但高效。复杂的版本采用合理的编码 除非您的文件太大,以至于您真的负担不起全部阅读,否则我只会使用:
var lastLine = File.ReadLines("file.txt").Last();
请注意,这使用的是,而不是。如果使用.NET 3.5或更早版本,则需要使用文件。ReadAllLines
或编写自己的代码-ReadAllLines
将一次性将整个文件读取到内存中,而ReadLines
将其流式处理
否则,复杂的方法是使用类似的代码。它尝试从文件末尾向后读取,处理诸如UTF-8多字节字符之类的不干净内容。这很不愉快。我会简单地组合并:
它对行进行流式处理,不会将所有行作为文件加载到内存中。ReadAllLines
第一部分:
File.ReadAllLines(@"c:\some\path\file.txt").Last();
或
首选读线。注意:所有这些代码都假定为UTF-8。如果需要支持使用双宽字符(如Unicode)的代码页,则需要在换行符之前和/或之后向字符添加额外的检查,以确保它确实是换行符
string m = "";
StreamReader r = new StreamReader("file_path");
while (r.EndOfStream == false)
{
m = r.ReadLine();
}
Console.WriteLine("{0}\n", m);
r.Close();
这个问题的一个主要用例是抓取日志文件的结尾。当日志文件达到兆字节时,其他答案不幸地消失了。想象一下,在一个小小的单核VPS上运行每次呼叫的每条线路。。。哎呀
UTF-8的好处在于,当您点击“\n”字符时,您不必担心任何依赖字节,因为UTF8-8中任何高位清除的字节都只是ASCII字符。非常方便
您可以在“”处使用解决方案,但请注意代码相当复杂。如果您只需要一个简单的UTF-8行预告片,此解决方案将工作得非常好,即使在大型日志文件上也会表现出色
如果您同时监视大量文件,并且在C#中使用类似FileSystemWatcher的东西,那么这种性能提升将非常重要。我在一个廉价的单cpu Linux VPS上使用非常类似的代码来监视登录失败,并在我的麻省理工学院授权项目中将ip地址放在防火墙中,使用(一次处理多个新行)
当SSH端口面向公众时,auth.log的大小会让您大吃一惊。如果您定期阅读几十个甚至数百个文件,您会很高兴没有使用File.ReadAllLines().Last()代码>
因为这只是一页代码,所以它在简单和快速之间取得了很好的平衡
C#代码
//
///实用程序类以性能敏感的方式从utf-8文本文件中读取最后一行。该代码不处理一次写入多行的情况。
///
公共静态类UTF8FileUtilities
{
///
///从文件中读取最后一行。此方法假定对文件的每次写入都将以新行字符(“\n”)终止
///
///要读取的文件的路径
///最后一行,如果无法读取某行(空文件或正在进行部分行写入),则为null
///打开或读取文件失败
公共静态字符串ReadLastLine(字符串路径)
{
//以只读方式打开,我们不希望有任何写入数据的机会
使用(System.IO.Stream fs=System.IO.File.OpenRead(path))
{
//检查是否有空文件
如果(fs.Length==0)
{
返回null;
}
//从文件末尾开始
fs.位置=fs.长度-1;
//如果没有进行部分行写入,则文件必须以“\n”字符结尾
int byteFromFile=fs.ReadByte();
如果(byteFromFile!='\n')
{
//正在进行部分行写入,请勿返回该行
返回null;
}
//移回新行字节-循环将再次递减位置,以到达它之前的字节
财政司司长职位-;
//虽然尚未到达文件的开头,但请向后读取字节,直到命中“\n”字节
而(fs.Position>0)
{
财政司司长职位-;
byteFromFile=fs.ReadByte();
if(byteFromFile<0)
{
//发生这种情况的唯一方法是,当我们反向读取时,有人从我们下面截取文件
抛出新System.IO.IOException(“从“+路径”处的文件读取时出错);
}
else if(byteFromFile=='\n')
{
//我们找到了新行,break out,fs。位置在“\n”字符后面
打破
}
财政司司长职位-;
}
//fs.Position将紧跟在“\n”字符之后,如果没有“\n”字符,则位置0
byte[]bytes=new System.IO.BinaryReader(fs.ReadBytes)((int)(fs.Length-fs.Position));
返回System.Text.Encoding.UTF8.GetString(字节);
}
}
}
您尝试过什么?请注意,我们只能在“1”方面提供帮助。。。“2”完全由你决定;fs.Seek(0,SeekOrigin.End);for(long offset=0;offsetFile.ReadLines(@"c:\some\path\file.txt").Last();
string m = "";
StreamReader r = new StreamReader("file_path");
while (r.EndOfStream == false)
{
m = r.ReadLine();
}
Console.WriteLine("{0}\n", m);
r.Close();
string last = File.ReadLines(@"C:\file.txt").Last();
string lastsymbol = last[last.Count - 1];
/// <summary>
/// Utility class to read last line from a utf-8 text file in a performance sensitive way. The code does not handle a case where more than one line is written at once.
/// </summary>
public static class UTF8FileUtilities
{
/// <summary>
/// Read the last line from the file. This method assumes that each write to the file will be terminated with a new line char ('\n')
/// </summary>
/// <param name="path">Path of the file to read</param>
/// <returns>The last line or null if a line could not be read (empty file or partial line write in progress)</returns>
/// <exception cref="Exception">Opening or reading from file fails</exception>
public static string ReadLastLine(string path)
{
// open read only, we don't want any chance of writing data
using (System.IO.Stream fs = System.IO.File.OpenRead(path))
{
// check for empty file
if (fs.Length == 0)
{
return null;
}
// start at end of file
fs.Position = fs.Length - 1;
// the file must end with a '\n' char, if not a partial line write is in progress
int byteFromFile = fs.ReadByte();
if (byteFromFile != '\n')
{
// partial line write in progress, do not return the line yet
return null;
}
// move back to the new line byte - the loop will decrement position again to get to the byte before it
fs.Position--;
// while we have not yet reached start of file, read bytes backwards until '\n' byte is hit
while (fs.Position > 0)
{
fs.Position--;
byteFromFile = fs.ReadByte();
if (byteFromFile < 0)
{
// the only way this should happen is if someone truncates the file out from underneath us while we are reading backwards
throw new System.IO.IOException("Error reading from file at " + path);
}
else if (byteFromFile == '\n')
{
// we found the new line, break out, fs.Position is one after the '\n' char
break;
}
fs.Position--;
}
// fs.Position will be right after the '\n' char or position 0 if no '\n' char
byte[] bytes = new System.IO.BinaryReader(fs).ReadBytes((int)(fs.Length - fs.Position));
return System.Text.Encoding.UTF8.GetString(bytes);
}
}
}