微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

是否有任何技巧来计算文本文件中的行数?

假设你有一个文本文件 – 确定文件中文本行数的最快和/或最有效的方法是什么?

是否只是逐个字符地扫描并寻找换行符?

为什么我不能添加WORKGROUP ..作为sql Server中的用户

Windows 10虚拟机上的Visual Studio性能较差

.NET或Windows同步基元性能规范

哪个.NET框架版本将被包含在Windows 7中?

你能以编程的方式看到USB设备在Windows中请求多less安培数?

可能不是最快的,但它将是最通用的…

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++; }

…这可能会更快…

如果你需要更多的速度,你可以试试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,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++; }

除非你有一个固定的行长度(以字节为单位 ),否则你肯定需要读取数据。 是否可以避免将所有数据转换为文本将取决于编码。

现在最有效的方法是重新计算行结束手动。 不过, 最简单的代码是使用TextReader.ReadLine() 。 事实上,最简单的方法是使用MiscUtil中的 LineReader类,它将文件名(或其他各种东西)转换为IEnumerable<string> 。 你可以使用LINQ:

int lines = new LineReader(filename).Count();

(如果你不想抓住整个MiscUtil,你可以从这个答案中自行获取LineReader 。)

现在,这将创建大量的垃圾,反复读取到相同的字符数组不会一次读取多个行,所以虽然你会强调GC一点,它不会用大文件炸毁。 它还需要将所有数据解码为文本 – 您可能无需进行某些编码就可以将其解码。

就个人而言,这是我使用的代码,直到我发现它造成了一个瓶颈 – 要比手动完成要简单得多。 你是否完全知道在你目前的情况下,像上面这样的代码将是瓶颈?

和以往一样,不要微观优化,直到你必须…而且你可以很容易地在以后的日期优化这个,而不改变你的整体设计,所以推迟它不会有任何伤害。

编辑:将马修的答案转换成适用于任何编码的答案 – 但这会招致解码所有数据的惩罚,当然,最终可能会有类似下面的代码。 我假设你只关心n而不是r , n和rn 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,buffer.Length)) > 0) { for (int i = 0; i < charsRead; i++) { if (buffer[i] == 'n') { count++; } } } return count; }

如果它是一个固定的记录,你可以得到一个记录的大小,然后除以该数量的总文件大小,以获得记录的数量。 如果你只是在寻找一个估计值,我过去所做的只是读取第一个x行(例如200),并用它来得出一个平均行大小,然后你可以用来猜测总数的记录(按平均行大小划分总文件大小)。 如果你的记录相当统一,而且你不需要一个确切的数字,这个效果很好。 我已经使用这个大文件(做一个快速检查,以获得文件大小,如果它超过20 MB,然后得到一个估计,而不是阅读整个文件)。

除此之外,唯一100%准确的方法是使用ReadLine逐行扫描文件

我一次只读32kb的数据,计算内存块中的 r n的数量并重复,直到完成。

最简单的:

int lines = File.ReadAllLines(fileName).Length;

这当然会把所有的文件都读入内存,所以根本不是内存高效的。 最有效的内存是将文件作为流读取并查找换行符。 这也是最快的,因为这是最小的开销。

没有捷径可以使用。 文件不是基于行的,所以没有额外的信息可以使用,另一种方法是读取和检查文件的每个字节。

我相信Windows使用两个字符来标记行结束(如果我记得正确的话,10H和13H),所以你只需要检查每两个字符对这两个字符。

由于这是一个纯粹的顺序过程,在位置之间没有依赖关系,所以如果数据真的很大,可以考虑映射/减少。 在C / C ++中,可以使用OpenMP进行并行处理。 每个线程将读取一个块并在该块中计数CRLF。 最后,在减少部分,他们将总结他们的个人数量。 英特尔线程构建模块为您提供了基于C ++模板的并行机制。 我同意这是一个文件大锤的方法,但从纯粹的性能角度来看,这是最佳的(分而治之)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐