如何在不读取整个文件的情况下找出文件有多少个字符



如果文件是一个文本文件,并且StreamReader可以找出它使用Encoding,如何在不读取整个文件的情况下找出它有多少个字符?

我正在读取 1GB CSV 文件,使用StreamReader读取它至少需要 4 秒。 File.ReadAllText().Length会导致System.OutOfMemoryException.

我想如果我有FileInfo(filename).LengthEncoding,那么我可以计算字符数。

你不能。原因是,某些编码(特别是 UTF-8)具有可变的字符宽度:某些字符仅占用 1 个字节 (ASCII),很多字符占用 2 个字节,甚至有些字符占用 3 个或更多字节。因此,如果不解码字符,就不可能知道编码下文件的长度。

此外,C# 字符串中的所有字符都表示为 UTF-16、AFAIK,因此,除非您有一个非常奇怪的文本(即您使用来自平面 0 之外的许多字符),否则您可以通过将字符数乘以 2 来相当容易地估计内存需求(反之亦然,通过将字节大小加倍来估计字符数)。

现在,一个更好的问题是 - 为什么需要字符数?您稍后要对CSV文件做什么,您想将其全部加载到内存中,为什么知道它的大小会有所帮助?

对于 ASCII、CP-437、CP-1252、ISO-8859-1 或类似的代码页,字符数将是字节数。

如果文件是 UTF-16,那么您无法从字节数中知道字符数,但它可能类似于字节数/2。在任何情况下,您都可以精确计算将文件保存在 .NET 字符串中所需的内存大小,因为它将是文件的大小(因为 .NET 内部使用 UTF-16)加上常量开销。此类字符串的长度将是字节数除以 2。

如果文件采用 UTF-8(或任何其他可用宽度的编码),则字符数的范围可能很宽,最多是字节数的几倍,也可能是每个字节一个字符。这只取决于数据。

如果文件采用 UTF-32(这极不可能),则字符数将恰好是文件的长度(以字节为单位)除以 4。但是,即使这是确切的字符数,它也不指示从此文件创建的 .NET 字符串的长度,因为这可能涉及对高平面中的字符使用代理项代码点,因此答案仍然取决于您打算如何处理这些信息。

我认为

它真的不能 - 某些编码对具有不同字节数的字符进行编码,因此您确实需要将字节转换为字符才能找到字符数。

例如,在 UTF-8 中,从 \u0000 到 \u007F 的字符仅以 1 个字节表示;在 \0u0080 和 \u07FF 之间,它们需要 2 个字节,依此类推。

对于某些编码,这有效(ASCII,Window 1262,IBM-850等),但不适用于UTF8和UTF7,因为它们有一些字符编码为1字节,一些编码为2(我相信有些甚至更多为2)。

这样做的问题是,如果文件是 UTF8 编码的,那么每个字符可以占用 1 到 4 个字节,因此您无法在不以某种方式处理文件的情况下"计算"字符数。

其他编码方法可能会更有成效。

相关内容

  • 没有找到相关文章

最新更新