xyz*_*xyz 8 .net c# windows text text-files
假设您有一个文本文件 - 确定该文件中文本行数的最快和/或最有效的内存方式是什么?
是否只是逐个字符地扫描它并寻找换行符?
Mat*_*ted 11
可能不是最快的,但它将是最多才多艺的......
int lines = 0;
/* if you need to use an encoding other than UTF-8 you way want to try...
new StreamReader("filename.txt", yourEncoding)
... instead of File.OpenText("myFile.txt")
*/
using (var fs = File.OpenText("myFile.txt"))
while (!fs.EndOfStream)
{
fs.ReadLine();
lines++;
}
Run Code Online (Sandbox Code Playgroud)
......这可能会更快......
如果您需要更高的速度,您可以尝试Duff的设备并在分支前检查10或20个字节
int lines = 0;
var buffer = new byte[32768];
var bufferLen = 1;
using (var fs = File.OpenRead("filename.txt"))
while (bufferLen > 0)
{
bufferLen = fs.Read(buffer, 0, 32768);
for (int i = 0; i < bufferLen; i++)
/* this is only known to work for UTF-8/ASCII other
file types may need to search for different End Of Line
characters */
if (buffer[i] == 10)
lines++;
}
Run Code Online (Sandbox Code Playgroud)
Jon*_*eet 10
除非你有一个固定的行长度(以字节为单位),否则你肯定需要读取数据.是否可以避免将所有数据转换为文本将取决于编码.
现在最有效的方法是重新加载 - 手动计算行结束.但是,最简单的代码是使用TextReader.ReadLine()
.实际上,最简单的方法是使用MiscUtil中的LineReader
类,它将文件名(或其他各种东西)转换为.然后你可以使用LINQ:IEnumerable<string>
int lines = new LineReader(filename).Count();
Run Code Online (Sandbox Code Playgroud)
(如果你不想获取整个MiscUtil,你可以LineReader
从这个答案中获得它自己.)
现在这会产生大量的垃圾,反复读入相同的char数组也不会 - 但它一次不会读取多行,所以虽然你会对GC有点压力,但它不会炸毁大文件.它还需要将所有数据解码为文本 - 您可以在不进行某些编码的情况下将其丢弃.
就个人而言,这是我使用的代码,直到我发现它导致了瓶颈 - 它比手动操作要简单得多.你是否完全知道在你目前的情况下,上面的代码会成为瓶颈?
与以往一样,不要微观优化,直到你必须...而且你可以在以后很容易地优化它而不改变你的整体设计,所以推迟它不会造成任何伤害.
编辑:将马修的答案转换为适用于任何编码的答案 - 但这将导致解码所有数据的惩罚,当然,您可能会得到类似下面的代码.我假设你只关心\n
-而不是\r
,\n
并且\r\n
它TextReader
通常用于处理:
public static int CountLines(string file, Encoding encoding)
{
using (TextReader reader = new StreamReader(file, encoding))
{
return CountLines(reader);
}
}
public static int CountLines(TextReader reader)
{
char[] buffer = new char[32768];
int charsRead;
int count = 0;
while ((charsRead = reader.Read(buffer, 0, buffer.Length)) > 0)
{
for (int i = 0; i < charsRead; i++)
{
if (buffer[i] == '\n')
{
count++;
}
}
}
return count;
}
Run Code Online (Sandbox Code Playgroud)
如果它是固定记录,您可以获取记录的大小,然后将总文件大小除以该数量以获得记录数.如果您只是在寻找估计值,那么我过去所做的只是读取前x行(例如200行)并使用它来得出平均行大小,然后您可以使用它来猜测总数记录(将文件总大小除以平均行大小).如果您的记录相当统一并且您不需要精确计数,则此方法很有效.我在大文件上使用了这个(快速检查以获取文件大小,如果它超过20 MB然后得到估计而不是读取整个文件).
除此之外,唯一100%准确的方法是使用ReadLine逐行浏览文件.