c# - 有没有更好的方法将任意输入转换为 ASCII?

标签 c# encoding stream ascii

我需要能够接受任意文本输入,其上可能带有字节顺序标记 (BOM) 以标记其编码,并将其输出为 ASCII。我们有一些不理解 BOM 的旧工具,我需要向它们发送纯 ASCII 数据。

现在,我刚刚写完这段代码,我简直不敢相信这里的效率低下。数据的四个副本,更不用说 StreamReader 内部的任何中间缓冲区了。有更好的方法吗?

// i_fileBytes is an incoming byte[]

string unicodeString = new StreamReader(new MemoryStream(i_fileBytes)).ReadToEnd();
byte[] unicodeBytes  = Encoding.Unicode.GetBytes(unicodeString.ToCharArray());
byte[] ansiBytes     = Encoding.Convert(Encoding.Unicode, Encoding.ASCII, unicodeBytes);
string ansiString    = Encoding.ASCII.GetString(ansiBytes);

我需要 StreamReader(),因为它有一个内部 BOM 检测器来选择编码来读取文件的其余部分。然后剩下的就是让它转换成最终的ASCII字符串。

有更好的方法吗?

最佳答案

如果内存中已经有 i_fileBytes,您可以只检查它是否以 BOM 开头,然后使用 Encoding.Unicode.GetString 转换整个文件或仅转换 BOM 之后的位。 (使用允许您指定索引和长度的重载。)

所以作为代码:

int start = (i_fileBytes[0] == 0xff && i_fileBytes[1] == 0xfe) ? 2 : 0;
string text = Encoding.Unicode.GetString(i_fileBytes, start, i_fileBytes.Length-start);

请注意,这假定了一个真正的小端 UTF-16 编码,但是。如果您真的需要首先检测编码,您可以重新实现 StreamReader 所做的,或者可能只是从前(比如说)10 个字节构建一个 StreamReader,然后使用 CurrentEncoding 属性来计算您应该 用于编码。

编辑:现在,至于转换为 ASCII - 如果您真的只需要它作为 .NET 字符串,那么您可能想要做的就是用“?”替换任何非 ASCII 字符。或类似的东西。 (或者,抛出异常可能更好……当然,这取决于您。)

编辑:请注意,在检测编码时,最好只调用一次 Read() 来读取一个字符。不要调用 ReadToEnd(),因为选择 10 个字节作为任意数量的数据,它可能会在字符中间结束。我不知道这是否会引发异常,但无论如何它没有任何好处......

关于c# - 有没有更好的方法将任意输入转换为 ASCII?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/309734/

相关文章:

c# - GroupPrincipal.Members.Remove() 不适用于大型 AD 组

c# - VS 2010 与 VS 2008 中 optionalAttribute(用于声明可选参数)行为的差异

c - 将 setvbuf() 与 STDIN 流一起使用

c# - 如何在运行时将文本框存储到数组中

java - 如何将 Cp1252 字节数组转换为正确的字符串?

java - 获取请求的 UTF-8 JSF 编码参数

python - 嵌套字典/json的分解与解码

java - 热衷于在 Java 中使用 Kafka Streams 创建差异流?

c++ - C++ 中用于字节 block 随机读/写的基本文件 I/O

c# - 排序列表并在排序后将特定元素保留在列表末尾