FileInfo.Length!=所有行长度的总和

时间:2015-04-14 08:30:21

标签: c#

我正在尝试为大文件阅读制作进度条。  我将进度条的最大值设置为FileInfo.Length,我使用StreamReader.ReadLine读取每一行并计算每个行长度的总和(使用String.Length)以设置进度条的当前值。

我注意到文件的总长度与每行长度之和存在差异。例如 : FileInfo.Length = 25577646 所有行长度的总和= 25510563

为什么会有这样的差异?

感谢您的帮助!

2 个答案:

答案 0 :(得分:6)

您没有添加行尾。它可以是1到4个字节,具体取决于编码,或者它是\n还是\r还是\r\n(1个字节= UTF8 + \n,4 bytes = UTF16 + \r\n

请注意,使用ReadLine时,无法检查哪一行(\n\r\r\n遇到了这一行

来自ReadLine

  

一行被定义为字符序列,后跟换行符(“\ n”),回车符(“\ r”)或回车符后紧跟换行符号(“\ r \ nn “)

其他问题:如果你的文件是UTF8,那么C#char长度与字节长度不同:è是C#中的一个char(使用UTF16),UTF8中有2个字符。你可以:

int len = Encoding.UTF8.GetByteCount(line);

答案 1 :(得分:5)

这里有两个问题:

  • string.Length为您提供每个字符串中字符的数量,而FileInfo.Length为您提供字节数。那些可能是非常不同的东西,取决于字符和使用的编码
  • 您不包括换行符(通常为\n\r\n),因为在使用TextReader.ReadLine
  • 读取行时会删除这些换行符

关于如何应对......

  • 您可能知道文件的编码,因此您可以通过调用Encoding.GetBytes将每行转换回字节来解释该差异。这样做会非常浪费。
  • 如果你知道文件使用的换行符,你可以为你读的每一行添加相关的字节数
  • 您可以保留对基础流的引用,并使用Stream.Position来检测您实际读取的文件的距离。但这不一定与您已经处理的数据量相同,因为StreamReader将有缓冲区。 (所以你很可能"看到" Stream已经阅读了所有数据,即使你还没有处理过所有的数据。)

最后一个想法可能是最干净的,IMO。