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

Sey*_*yoS 4 c#

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

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

为什么会有这样的差异?

谢谢你的帮助 !

xan*_*tos 6

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

请注意,由于ReadLine无法检查哪一行(\n\r\r\n遇到)

来自ReadLine:

一行被定义为一个字符序列,后跟一个换行符("\n"),一个回车符("\ r"),或一个回车符后面紧跟一个换行符("\ r \n")

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

int len = Encoding.UTF8.GetByteCount(line);
Run Code Online (Sandbox Code Playgroud)


Jon*_*eet 5

这里有两个问题:

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

关于如何做到这一点......

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

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