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

C# 有没有更好的方法将任意输入转换为ASCII码?,c#,encoding,stream,ascii,C#,Encoding,Stream,Ascii,我需要能够接受一个任意的文本输入,它可能有一个字节顺序标记(BOM),以标记其编码,并将其输出为ASCII。我们有一些不理解BOM的旧工具,我需要向它们发送ASCII数据 现在,我刚写完这段代码,我简直不敢相信这里的效率低下。数据的四个副本,更不用说StreamReader内部的任何中间缓冲区了。有更好的方法吗 // i_fileBytes is an incoming byte[] string unicodeString = new StreamReader(new MemoryStrea

我需要能够接受一个任意的文本输入,它可能有一个字节顺序标记(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\u fileBytes,您可以检查它是否以BOM开头,然后使用
Encoding.Unicode.GetString
转换整个BOM或BOM后面的位。(使用重载可以指定索引和长度。)

// 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);
代码如下:

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个字节作为任意数量的数据,它可能会以中间字符结尾。我不知道这是否会引发异常,但无论如何它都没有好处

System.Text.Encoding.ASCII.GetBytes(new StreamReader(new MemoryStream(i_fileBytes)).ReadToEnd())

这应该可以节省一些往返行程。

是的,这就是我一直在考虑和想要避免的。我可以使用Reflector从StreamReader中提取BOM检测内容。虽然不是很干净,也不适合未来。不过,使用StreamReader只获取前10个字节是很有趣的。好主意!