首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何告诉ASCIIEncoding类不要解码字节顺序标志

如何告诉ASCIIEncoding类不要解码字节顺序标志
EN

Stack Overflow用户
提问于 2011-02-24 07:43:18
回答 3查看 3.6K关注 0票数 1

当使用.net ASCIIEncoding类将字节数组解码为字符串时,我是否需要编写一些代码来检测和删除字节顺序标记,或者是否可以告诉ASCIIEncoding不要将字节顺序标记解码为字符串?

这是我的问题,当我这样做的时候:

代码语言:javascript
复制
string someString = System.Text.ASCIIEncoding.Default.GetString(someByteArray)

someString将如下所示:

代码语言:javascript
复制
<?xml version="1.0"?>.......

然后当我调用这个的时候:

代码语言:javascript
复制
XElement.Parse(someString)

由于前三个字节引发异常: EF、BB、BF - UTF8字节顺序标记。所以我想,如果我指定UTF8编码,而不是缺省编码,就像这样:

代码语言:javascript
复制
System.Text.ASCIIEncoding.UTF8.GetString(someByteArray)

ASCIIEncoding不会尝试将字节顺序标记解码为字符串。当我将返回的字符串复制到notepad++中时,可以看到?XML标记前面的字符。因此,现在字节顺序标记被解码为一个垃圾字符。在这种情况下,停止对字节顺序标记进行解码的最佳方法是什么?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-02-24 07:49:47

请不要使用

代码语言:javascript
复制
ASCIIEncoding.UTF8

那真的只是

代码语言:javascript
复制
Encoding.UTF8

它根本没有使用ASCIIEncoding。它只是在你的源代码中看起来很像。

从根本上说,问题是您的文件是UTF-8,而不是ASCII。这就是为什么它有一个UTF-8字节顺序标记。我强烈建议您使用Encoding.UTF8来读取UTF-8文件,不管用哪种方式。

如果您使用File.ReadAllText读取该文件,我怀疑它会自动删除该物料清单。或者,您可以在调用XElement.Parse之前对其进行修剪。使用错误的编码( ASCII或Encoding.Default)不是正确的方法。同样,它也不是一个垃圾字符。它是一个非常有用的字符,强烈地表明它确实是一个UTF-8文件--只是在这个特定的上下文中你不需要它。“垃圾”给人的印象是它是损坏的数据,不应该出现在文件中,但事实绝对不是这样的。

另一种方法是完全避免将其转换为文本。例如:

代码语言:javascript
复制
XElement element;
using (XmlReader reader = XmlReader.Create(new MemoryStream(bytes))
{
    element = XElement.Load(reader);
}

这样编码将被自动检测到。

票数 5
EN

Stack Overflow用户

发布于 2011-02-24 08:58:07

System.Text.Encoding.GetString()会保留物料清单(如果存在)并将其转换为UTF-16物料清单(U+FEFF)。把这看作是一个特性。严格地说,这是正确的做法,因为抛出BOM会使转换有损失,并且不能往返。然而,有些令人惊讶的是,他们没有提供一个标志来让你指定想要的行为,但你就是这样。所以...你有两个选择:

  1. 转换为字符串,查找物料清单并在对该字符串调用XElement.Parse()之前将其删除。或者...
  2. byte[]包装在MemoryStream中,将MemoryStream包装在StreamReader中,并使用XElement.Load()进行解析。

你自己选吧。下面是一些可以工作的示例代码:

代码语言:javascript
复制
using System.IO;
using System.Text;
using System.Xml.Linq;

namespace TestDrive
{
    class Program
    {
        public static void Main()
        {
            byte[] octets = File.ReadAllBytes( "utf8-encoded-document-with-BOM.xml" ) ;

            // -----------------------------------------------
            // option 1: use a memory stream and stream reader
            // -----------------------------------------------
            using ( MemoryStream ms = new MemoryStream( octets) )
            using ( StreamReader sr = new StreamReader( ms , Encoding.UTF8 , true )   )
            {
                XElement element1 = XElement.Load( sr ) ;
            }

            // --------------------------------------------------------------------
            // option 2: convert to string, then look for and remove BOM if present
            // 
            // The .Net framework Encoding.GetString() methods preserve the BOM if
            // it is present. Since the internal format of .Net string is UTF-16,
            // the BOM is converted to the UTF-16 encoding (U+FEFF).
            // 
            // Consider this a feature.
            // --------------------------------------------------------------------
            // convert to UTF-16 string
            string       xml       = Encoding.UTF8.GetString( octets ) ;
            // Two different ways of getting the BOM
            //string UTF16_BOM = Encoding.Unicode.GetString(Encoding.Unicode.GetPreamble()).ToCharArray() ;
            const string UTF16_BOM = "\uFEFF" ; 
            // parse the element, removing the BOM if we see it.
            XElement element2 = XElement.Parse( xml.StartsWith( UTF16_BOM ) ? xml.Substring(1) : xml ) ;

            return ;
        }
    }
}
票数 2
EN

Stack Overflow用户

发布于 2011-02-24 08:00:03

这不是一个答案,但是注释中的代码是可怕的,在你的问题中加入这一点感觉有点粗鲁。你真的想这么做吗:

代码语言:javascript
复制
Byte[] bytes = new byte [] { 0xEF,0xBB,0xBF, 0x57, 0x44 };
String txt = Encoding.UTF8.GetString(bytes);
Console.WriteLine("String length {0}", txt.Length);
Console.WriteLine("String '{0}'", txt);
Console.WriteLine("Chars '{0}'", String.Join(",", txt.Select(chr => ((int)chr).ToString("x2"))));

想知道为什么你会得到:

代码语言:javascript
复制
String length 3
String 'WD'
String 'feff,57,44'

我当然是……

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5098757

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档