如果文件是文本文件,StreamReader
可以找出它使用的Encoding
,如何在不读取整个文件的情况下找出它有多少字符?
我正在阅读1GB的CSV文件,用StreamReader
读取它需要至少4秒钟。 File.ReadAllText().Length
会导致System.OutOfMemoryException
。
我想如果我有FileInfo(filename).Length
和Encoding
,那么我就可以计算出字符数。
答案 0 :(得分:4)
你做不到。原因是,某些编码(特别是UTF-8)具有可变的字符宽度:某些字符仅占用1个字节(ASCII),大量占用2个字节,甚至有每个字符3个或更多字节的情况。因此,在不解码字符的情况下,不可能在编码下知道文件的长度。
此外,C#字符串中的所有字符都表示为UTF-16,AFAIK,因此,除非您有一个非常奇怪的文本(即您使用来自外部plane 0的许多字符),您可以估计内存要求以字节为单位,通过将字符数乘以2(反之亦然,通过将字节大小加倍来估算字符数)。
现在,一个更好的问题是 - 你为什么需要字符数?你以后用CSV文件做什么,你想把它全部加载到内存中,为什么知道它的大小有帮助呢?
答案 1 :(得分:1)
对于ASCII,CP-437,CP-1252,ISO-8859-1或类似这些的代码页,则字符数将是字节数。
如果文件是UTF-16,那么你不能从字节数中知道字符数,但它可能类似于字节数/ 2.无论如何,你可以准确地计算出将文件保存在.NET字符串中所需的内存大小,因为它将是文件的大小(因为.NET在内部使用UTF-16)加上常量开销。这样一个字符串的长度将是字节数除以2。
如果文件是UTF-8(或任何其他可变宽度编码),那么字符数可以是宽范围,最多可达字节数的几倍,也可以是每字节一个字符。它只取决于数据。
如果文件是UTF-32(极不可能),那么字符数就是文件的长度,以字节为单位除以4。但即使这是确切的字符数,也不表示从该文件创建的.NET字符串的长度,因为这可能涉及在高平面中使用代理代码点,因此答案仍然取决于你对这些信息的了解。
答案 2 :(得分:0)
我不认为它真的可以 - 某些编码会编码具有不同字节数的字符,因此您需要将字节转换为字符以查找字符数。
例如,在UTF-8中,\ u0000到\ u007F中的字符仅以1个字节表示;在\ 0u0080和\ u07FF之间,它们需要2个字节,依此类推。
答案 3 :(得分:0)
对于某些编码,这适用(ASCII,Window 1262,IBM-850等),但不适用于UTF8和UTF7,因为它们有一些字符编码为1字节,有些编码为2(我相信有些甚至更多为2) )。
答案 4 :(得分:0)
问题是如果文件是UTF8编码的,那么每个字符可以占用1到4个字节,因此你无法以某种方式“计算”字符数而不处理文件。
其他编码方法可能会更有成效。