《WCF技术内幕》翻译22:第2部分_第5章_消息:XmlDictionaryWriter

Posted on 2009-12-01 20:26 Frank Xu Lei 阅读(230) 评论(2)   编辑 收藏 网摘 所属分类: 《WCF技术内幕》翻译, SOA and EAI 1614830.html?type=1&webview=1

(概述:这一部分介绍了XmlDictionaryWriter类型的相关概念:如何创建,使用一个对象,然后讲述了如何进行Text、二进制和MTOM编码。最后介绍了XmlDictionary的作用【老徐备注2】,已经各种编码的效率问题。你会了解为WCF支持的几种编码格式的基本原理。)

XmlDictionaryWriter

XmlDictionaryWriter类型为Message类型的序列化和编码的。它继承自System.Xml.XmlWriter,因此继承了很多XmlWriter的属性。像XmlWriter一样,XmlDictionaryWriter也是抽象类型,它定义了几个返回XmlDictionaryWriter子类型实例的方法,包装了System.IO.Stream并且定义了许多以Write单词开始的方法。在作用上,程序里使用XmlDictionaryWriter和XmlWriter在概念上十分相似。

XmlWriter不同,XmlDictionaryWriter类型的目的是序列化和编码Message对象,并且有时会使用XmlDictionary对象处理压缩工作。为了这一目的,XmlDictionaryWriter类型定义了一些与XmlWriter不同的成员。让我们通过研究这些成员来详细了解一下XmlDictionaryWriter类型。首先我们会检查一下XmlDictionaryWriter的构造函数,然后看看如何通过Stream序列化和编码XML数据。

创建一个XmlDictionaryWriter对象

XmlDictionaryWriter定义了几个工厂方法,并且它们都直接或者间接地接受System.IO.Stream对象的引用。这些方法大部分是重载一下4个方法:CreateDictionaryWriter、CreateTextWriter、CreateMtomWriter和CreateBinaryWriter。

CreateDictionaryWriter  XmlDictionaryWriter 类型上的工厂方法CreateDictionaryWriter其中之一就是接受一个XmlWriter类型的引用。内部来说,这些方法返回的实例都是简单地包装了传递的参数XmlWriter。因此,这些方法用处不大,除了某些API里需要XmlDictionaryWriter类型的时候。比如,你可能要掉也难怪一个接受XmlDictionaryWriter类型参数的方法,但是你只有一个XmlWriter类型的局部变量。假如这样的话,你可以通过调用CreateDictionaryWriter工厂方法,传递XmlWriter参数,从XmlWriter创建XmlDictionaryWriter对象,代码如下:

MemoryStream stream = new MemoryStream();
XmlWriter xmlWriter = XmlWriter.Create(stream);
XmlDictionaryWriter writer = XmlDictionaryWriter.CreateDictionaryWriter(xmlWriter);

 

CreateTextWriter  XmlDictionaryWriter类型定义了三个工厂方法。这些工厂方法返回的是继承自XmlDictionaryWriter类型的实例,并且它们的作用是为了产生基于文本编码的XML。所有的三个方法都接受Stream类型的参数。两个方法接受一个Stream参数和一个System.Text.Encoding类型的参数。一个方法接受一个Stream类型、一个Encoding和一个Boolean类型的参数。Encoding参数,如你所期望的,设置处理Stream时候的编码格式。虽然有很多编码格式,但是CreateTextWriter方法只支持三种编码格式:UTF-8 、Unicode (UTF-16) little-endian和big-endian方式。如果不选择的话,默认使用UTF-8编码。Boolean参数表示XmlDictionaryWriter是否拥有这个Stream对象。如果为true, 调用XmlDictionaryWriter上的Close 和Dispose方法,也会调用Stream对象的Close方法,因此能够阻止对Stream 的后续访问。如果没有设置的话,默认为true.下面的代码演示了如何使用CreateTextWriter方法:

 
   
MemoryStream stream  =   new  MemoryStream();
using  (XmlDictionaryWriter writer  =
 XmlDictionaryWriter.CreateTextWriter(stream, Encoding.UTF8, 
false )) {
      writer.WriteStartDocument();
      writer.WriteElementString(
" SongName " ,
                                
" urn:ContosoRockabilia " ,
                                
" Aqualung " );
      writer.Flush();
}
 
Console.WriteLine(
" XmlDictionaryWriter (Text-UTF8) wrote {0} bytes " ,
                  stream.Position);
 stream.Position 
=   0 ;
 Byte[] bytes 
=  stream.ToArray();
 Console.WriteLine(BitConverter.ToString(bytes));
 Console.WriteLine(
" data read from stream:/n{0}/n " ,
    
new  StreamReader(stream).ReadToEnd());

当代码运行的时,它会产生下面的输出:
XmlDictionaryWriter (Text-UTF8) wrote 97 bytes3C-3F-78-6D-6C-20-76-65-72-73-69-6F-6E-3D-22-31-2E-30-22-20-65-6E-63-6F-64-69-6E-67-3D-2275-74-66-2D-38-22-3F-3E-3C-53-6F-6E-67-4E-61-6D-65-20-78-6D-6C-6E-73-3D-22-75-72-6E-3A-436F-6E-74-6F-73-6F-52-6F-63-6B-61-62-69-6C-69-61-22-3E-41-71-75-61-6C-75-6E-67-3C-2F-53-6F6E-67-4E-61-6D-65-3E
data read from stream:

Aqualung

注意到XmlDictionaryWriter放在Using结构里,因此可以确保Dispose方法的被调用。但是Stream对象在using体结束后依然可用;这可能因为CreateTextWriter的Boolean参数设置为false了。当使用UTF-8编码的时候,字节顺序标记(BOM)忽略了。如果选择Unicode编码,输出结果会包含标准的UTF-16 little-endian BOM(FF FE).

CreateMtomWriter  XmlDictionaryWriter定义了两个CreateMtomWriter方法。这些方法放回的是继承自XmlDictionaryWriter并且产生MTOM编码的XML的实例。两者都接受一个Stream类型的参数和几个别的控制XML Infoset编码的参数。这些参数设置编码格式、SOAP消息头的ContentType、多用途网络邮件扩展协议(MIME)的边界和MIME的统一资源标识符(URI),同时也包括是否把消息写入Stream对象。对于CreateTextWriter方法,支持的编码是UTF-8 、Unicode (UTF-16) little-endian和big-endian方式。下面代码演示了如何调用CreateMtomWriter方法:

MemoryStream stream = new MemoryStream();
using (XmlDictionaryWriter writer =
 XmlDictionaryWriter.CreateMtomWriter(stream, Encoding.UTF8, 1000,
                                       "Application/soap+xml")) {
 writer.WriteStartDocument();
 writer.WriteElementString("SongName",
                            "urn:ContosoRockabilia",
                            "Aqualung");
 writer.Flush();
}
Console.WriteLine("XmlDictionaryWriter (MTOM-UTF8) wrote {0} bytes",
                   stream.Position);
stream.Position = 0;
Byte[] bytes = stream.ToArray();
Console.WriteLine(BitConverter.ToString(bytes));
Console.WriteLine("data read from stream:/n{0}/n",
    new StreamReader(stream).ReadToEnd());

当代码执行的时候,它会产生下面的结果。(为了简洁省略了一些内容。)

XmlDictionaryWriter (MTOM-UTF8) wrote 576 bytes
4D-49-4D-45-2D-56-65-72-73-69-6F-6E-3A-20-31-2E-30-0D-0A-43-6F-6E-74-65-6E-74-2D-54-79-70
65-3A-20-6D-75-6C-74-69-70-61-72-74-2F-72-65-6C-61-74-65-64-3B-74-79-70-65-3D-22-61-70-70
6C-69-63-61-74-69-6F-6E-2F-78-6F-70-2B-78-6D-6C-22-3B-62-6F-75-6E-64-61-72-79-3D-22-37-31
65-37-62-35-32-61-2D-37-61-34-36-2D-34-37-32-36-2D-62-61-62-64-2D-31-37-37-32-32-39-65-32
38-66-30-33-2B-69-64-3D-31-22-3B-73-74-61-72-74-3D-22-3C-68-74-74-70-3A-2F-2F-74-65-6D-70
75-72-69-2E-6F-72-67-2F-30-2F-36-33-32-38-37-31-37-34-35-30-37-30-38-39-31
data read from stream:
MIME-Version: 1.0
Content-Type: multipart/related;
 type="application/xop+xml";
 boundary="+id=1";
 start="";
 start-info="Application/soap+xml"
--+id=1
Content-ID: 
Content-Transfer-Encoding: 8bit
Content-Type: application/xop+xml; charset=utf-8;
   type="Application/soap+xml"
 
    Aqualung
 
--+id=1–

下面代码演示了调用其它的CreateMtomWriter方法产生不同的结果:

MemoryStream stream = new MemoryStream();
using (XmlDictionaryWriter writer =
 XmlDictionaryWriter.CreateMtomWriter(stream,
                                       Encoding.UTF8,
                                       1000,
                                       "startInfo",
                                       "boundary",
                                       "urn:startUri",
                                       false,
                                       false)){
      writer.WriteStartDocument();
      writer.WriteElementString("SongName",
                                "urn:ContosoRockabilia",
                                "Aqualung");
      writer.Flush();
 }
Console.WriteLine("XmlDictionaryWriter (MTOM-UTF8) wrote {0} bytes",
    stream.Position);
stream.Position = 0;
Byte[] bytes = stream.ToArray();
Console.WriteLine(BitConverter.ToString(bytes));
Console.WriteLine("data read from stream:/n{0}/n",
 new StreamReader(stream).ReadToEnd());

当代码执行的时候,它会产生下面的结果。(为了简洁省略了一些内容。)

XmlDictionaryWriter (MTOM-UTF8) wrote 256 bytes
0D-0A-2D-2D-62-6F-75-6E-64-61-72-79-0D-0A-43-6F-6E-74-65-6E-74-2D-49-44-3A-20-3C-75-72-6E
3A-73-74-61-72-74-55-72-69-3E-0D-0A-43-6F-6E-74-65-6E-74-2D-54-72-61-6E-73-66-65-72-2D-45
6E-63-6F-64-69-6E-67-3A-20-38-62-69-74-0D-0A
data read from stream:
 
--boundary
Content-ID: 
Content-Transfer-Encoding: 8bit
Content-Type: application/xop+xml;charset=utf-8;type="startInfo"
 
 Aqualung
--boundary–

注意到第二个CreateMtomWriter方法的参数映射到MTOM编码数据的不同位置。同样注意到倒数第二个位置的参数也被设置为false,这是为了去掉Stream开始部分的多消息头。

当调用CreateMtomWriter方法时,要加倍小心。两个CreateMtomWriter方法都使用MTOM方式序列化和编码XML Infosets,而第二个方法对于数据编码提供了更多的控制。明显地,第二个方法有更大的好处,它允许我们对数据格式做更多控制。肯定有程序需要这种级别的控制。如果接受者无法解释消息,这种控制就引入了阻断互操作的可能性。正如你在第2章里看到的一样,使用MTOM一个主要的动机就是互操作性,所以如果使用不当,就会违背使用MTOM的初衷。

CreateBinaryWriter  XmlDictionaryWriter也定义了4个CreateBinaryWriter方法。这些方法返回的是继承自XmlDictionaryWriter能产生二进制编码的XML的实例。所有的方法都接受一个Stream参数。三个方法接受一个XmlDictionary参数,两个接受XmlBinaryWriterSession参数,一个也接受Boolean参数。如果设定的话,XmlDictionary参数表示用于压缩的XmlDictionary对象。如果内有压缩需求,可以传递null参数。为了与CreateTextWriter风格的统一,CreateBinaryWriter方法也有一个Boolean变量,它表示XmlDictionaryWriter是否拥有Stream对象。

CreateBinaryWriter方法上的XmlBinaryWriterSession参数允许发送者和接收者自动创建和协调一个动态的XmlDictionary。如前面提到的一样,在使用之前,key-value对必须添加到XmlDictionary对象。XmlDictionary内容必须在消息参与者之间共享(典型的是在out-of-band机制中)。在消息参与者之间共享XmlDictionary的内容是一个很大的挑战,而XmlBinaryWriterSession应付了大部分挑战。在Stream 开始的时候,XmlBinaryWriterSession类型生成key-value对,因此去掉了共享XmlDictionary的需求。内部来看,XmlBinaryWriterSession维持有自己的XmlDictionary,并且增加XmlDictionaryString对象作为names、attribute names和XML namespaces在被序列化的内容里。XmlBinaryWriterSession产生数据不像通过XmlDictionary和二进制编码序列化数据,但是XmlBinaryWriterSession不会强迫我们事先知道XmlDictionary或者手动协调XmlDictionary和接收者。为了在数据接收结束之后解码数据,接收者比如使用XmlBinaryReaderSession对象。XmlBinaryReaderSession对象首先会自动从Stream对象初始化自身的数据信息。作用上,XmlBinaryWriterSession类型动态创建和协调一个XmlDictionary对象,但是这样也会有性能代价。

注释:注意到在整个XmlDictionaryWriter类型介绍里这是第一次提到XmlDictionary。正如所料,基于二进制编码的XML是唯一合乎逻辑的语义压缩方式。 所有其他的方法都是设计来产生文本编码的。从本性上说,UTF-8 和UTF-16文本编码是定义明确的,与二进制编码压缩的方式不同。也有一些别的定义清晰的压缩文本数据的机制(GZIP、霍夫曼编码等等)。很有意思的一点是XmlDictionaryWriter类型能够处理多种编码,但是目前只指定了一种二进制编码功能。

下面代码展示了如何不使用XmlDictionary参数调用CreateBinaryWriter方法。(你会在本章后面看到如何使用XmlDictionary。)

MemoryStream stream = new MemoryStream();
using (XmlDictionaryWriter writer =
    XmlDictionaryWriter.CreateBinaryWriter(stream, null, null)) {
 writer.WriteStartDocument();
 writer.WriteElementString("SongName",
                            "urn:ContosoRockabilia",
                            "Aqualung");
 writer.Flush();
 Console.WriteLine(
    "XmlDictionaryWriter (Binary, no dictionary) wrote {0} bytes",
    stream.Position);
 stream.Position = 0;
 
 Byte[] bytes = stream.ToArray();
 Console.WriteLine(BitConverter.ToString(bytes));
}

当代码执行的时候,它会产生下面的结果:

XmlDictionaryWriter (Binary, no dictionary) wrote 43 bytes
3F-08-53-6F-6E-67-4E-61-6D-65-04-15-75-72-6E-3A-43-6F-6E-74-6F-73-6F-52-6F-63-6B-61-62-69
6C-69-61-A1-08-41-71-75-61-6C-75-6E-67

Write方法

我们已经看过了不同创建XmlDictionaryWriter对象的方法,让我们研究一下如何使用这个对象写XML。如前所述,XmlDictionaryWriter为把XML写入Stream对象定义了许多方法,这些方法名都以XmlWriter开始。XmlDictionaryWriter定义了几个满足消息应用需求的方法。为了避免重复叙述文档,本章不会阐述XmlDictionaryWriter模仿XmlWriter的特性,而是关注在XmlDictionaryWriter的新特性上:使用XmlDictionary对象。

使用XmlDictionary

许多XmlDictionaryWriter的写方法包含XmlDictionaryString类型的参数。这些方法基本都是成对出现,而且接受的都是String类型的参数。思考一下XmlDictionaryWriter里的2个方法原型:

// method accepting String objects
public void WriteElementString(String localName,
                               String ns,
                               String value);
 
// method accepting XmlDictionaryString and String objects
public void WriteElementString(XmlDictionaryString localName,
                               XmlDictionaryString namespaceUri,
                               String value);

注意到2个方法都包含3个参数,第二个方法为了局部name和namespace简单地接受2个XmlDictionaryString参数。重要的是知道第一个方法定义在XmlWriter类型上,而第二个方法定义在XmlDictionaryWriter类型上。考虑到这些,你也许想知道他们的区别。为了答案,我们要测试一下2个方法,然后比较结果。下面的代码使用接受三个String参数的WriteElementString方法:

private static void UseTextWriter() {
 MemoryStream stream = new MemoryStream();
 
 using (XmlDictionaryWriter writer =
      XmlDictionaryWriter.CreateTextWriter(stream, Encoding.UTF8, true)) {
    writer.WriteElementString("SongName",
                              "urn:ContosoRockabilia",
                              "Aqualung");
    writer.Flush();
    Console.WriteLine("XmlDictionaryWriter (Text-UTF8) wrote {0} bytes",
                      stream.Position);
    stream.Position = 0;
    Byte[] bytes = stream.ToArray();
 
    Console.WriteLine(BitConverter.ToString(bytes));
    Console.WriteLine("data read from stream:/n{0}/n",
      new StreamReader(stream).ReadToEnd());
 }
}

当代码执行的时候,它会产生下面的结果:

XmlDictionaryWriter (Text-UTF8) wrote 59 bytes
3C-53-6F-6E-67-4E-61-6D-65-20-78-6D-6C-6E-73-3D-22-75-72-6E-3A-43-6F-6E-74-6F-73-6F-52-6F
63-6B-61-62-69-6C-69-61-22-3E-41-71-75-61-6C-75-6E-67-3C-2F-53-6F-6E-67-4E-61-6D-65-3E
data read from stream:
   Aqualung

下面运行一段相似的代码,但是这次,调用接受XmlDictionaryString 参数的WriteElementString方法:

private static void UseTextWriterWithDictionary() {
 MemoryStream stream = new MemoryStream();
 
 // build the dictionary and populate构建字典并填充字典
 XmlDictionary dictionary = new XmlDictionary();
 List stringList = new List();
 stringList.Add(dictionary.Add("SongName"));
 stringList.Add(dictionary.Add("urn:ContosoRockabilia"));
 
 using (XmlDictionaryWriter writer =
      XmlDictionaryWriter.CreateTextWriter(stream, Encoding.UTF8, true)) {
    writer.WriteElementString(stringList[0], stringList[1], "Aqualung");
    writer.Flush();
    Console.WriteLine("XmlDictionaryWriter (Text-UTF8) wrote {0} bytes",
                      stream.Position);
    stream.Position = 0;
    Byte[] bytes = stream.ToArray();
 
    Console.WriteLine(BitConverter.ToString(bytes));
    Console.WriteLine("data read from stream:/n{0}/n",
                      new StreamReader(stream).ReadToEnd());
 }
}

这些代码会产生下面的结果

XmlDictionaryWriter (Text-UTF8) wrote 59 bytes
3C-53-6F-6E-67-4E-61-6D-65-20-78-6D-6C-6E-73-3D-22-75-72-6E-3A-43-6F-6E-74-6F-73-6F-52-6F
63-6B-61-62-69-6C-69-61-22-3E-41-71-75-61-6C-75-6E-67-3C-2F-53-6F-6E-67-4E-61-6D-65-3E
data read from stream:
Aqualung

2个方法产生相同的输出结果!当使用XmlDictionary时,我们期望的依照语法的压缩没有发生。如在XmlDictionaryWriter的讨论里说的一样,XmlDictionary只有在XmlDictionaryWriter产生二进制编码的XML的时候才会有用。但是对于产生二进制编码XML的XmlDictionaryWriter方法来说,使用XmlDictionary是不受限制的。这个特性非常有用,为了弄个明白,思考一下下面的方法:

// assume that stringList contains XmlDictionaryString objects假设stringList包括XmlDictionaryString
// and is populated before this method is called并且已经填充完毕
private static void WriteSomeXml(XmlDictionaryWriter writer) {
 writer.WriteElementString(stringList[0], stringList[1], "Aqualung");
}

WriteSomeXml接受任何继承自XmlDictionaryWriter类型的参数。包含生成二进制编码XML的XmlDictionaryWriter类型,也包括生成文本编码XMl的类型。由于XmlDictionaryWriter编码的灵活性,WriteSomeXml方法可以根据不同的编码来输出XML数据。换句话说,可以接受XmlDictionaryString参数的WriteElementString的重载方法带来的是一个灵活的API。

如果我们调用CreateBinaryWriter工厂方法创建一个XmlDictionaryWriter对象,然后调用Write方法,我们会看到Stream里一个完全不同的数据集。代码演示如下:

 // create the dictionary and add dictionary strings创建字典并添加字符
 XmlDictionary dictionary = new XmlDictionary();
 List stringList = new List();
 stringList.Add(dictionary.Add("SongName"));
 stringList.Add(dictionary.Add("urn:ContosoRockabilia"));
MemoryStream stream = new MemoryStream();
using (XmlDictionaryWriter writer =
    XmlDictionaryWriter.CreateBinaryWriter(stream, dictionary, null)) {
 // write using the dictionary - element name, namespace, value
 writer.WriteElementString(stringList[0], stringList[1], "Aqualung");
 writer.Flush();
 Console.WriteLine("Using XmlDictionary w/Binary , wrote {0} bytes",
                    stream.Position);
 stream.Position = 0;
 Byte[] bytes = stream.ToArray();
 Console.WriteLine(BitConverter.ToString(bytes));
}

当代码执行的时候,它会产生下面的结果:

Using XmlDictionary w/Binary, wrote 14 bytes
42-00-0A-02-99-08-41-71-75-61-6C-75-6E-67

注意到XmlDictionary使用二进制编码比文本编码大小减少了75%(14 字节 vs. 59 字节)。在Stream里,使用XmlDictionaryString整型key替换的string的值,这一替换压缩了数据的存储空间。记住前面代码里对元素name(SongName) 和 namespace (urn:ContosoRockabilia)的替换。在此强调一下这一点,下面代码演示了如何不使用XmlDictionary实例直接生成二进制XML数据:

private static void UseBinaryWriter() {
 MemoryStream stream = new MemoryStream();
 using (XmlDictionaryWriter writer =
      XmlDictionaryWriter.CreateBinaryWriter(stream, null, null)) {
    writer.WriteElementString("SongName",
                              "urn:ContosoRockabilia",
                              "Aqualung");
    writer.Flush();
    Console.WriteLine("Not Using XmlDictionary w/Binary, wrote {0} bytes",
                      stream.Position);
    stream.Position = 0;
    Byte[] bytes = stream.ToArray();
    Console.WriteLine(BitConverter.ToString(bytes));
 }
}

当代码执行的时候,它会产生下面的结果:

Not Using XmlDictionary w/Binary, wrote 43 bytes
3F-08-53-6F-6E-67-4E-61-6D-65-04-15-75-72-6E-3A-43-6F-6E-74-6F-73-6F-52-6F-63-6B-61-62-69
6C-69-61-A1-08-41-71-75-61-6C-75-6E-67

在我们的测试里, 与不使用XmlDictionary的二进制编码相比,使用XmlDictionary的二进制编码减少了67%的大小。进一步了解XmlDictionary和XmlDictionaryWriter的目的,让我们再看一下使用文本编码、二进制编码在不使用和使用dictionary时候的字节顺序,

XML to be encoded:
Aqualung
XmlDictionaryWriter (Text-UTF8) wrote 59 bytes
 
   
 
   
 
   
XmlDictionaryWriter (binary) No XmlDictionary wrote 43 bytes
 
   
 
   
 
   
 
XmlDictionaryWriter (binary), With XmlDictionary wrote 14 bytes
 
   

注意黑体的字节顺序。如果我们把这些字节转换为ASCII字符,我们会看到下面的ASCII-到-byte的转换:

 
   
SongName
53-6F-6E-67-4E-61-6D-65
urn:ContosoRockabilia
75-72-6E-3A-43-6F-6E-74-6F-73-6F-52-6F-63-6B-61-62-69-6C-69-61
Aqualung
41-71-75-61-6C-75-6E-67

基于前面的例子,我们知道产生二进制编码XML的XmlDictionaryWriter不使用XmlDictionary来直接编写元素name、XML namespaces、attribute values和element values到Stream。当然XmlDictionaryWriter也可以使用XmlDictionary实例来生成带有原书和属性值的二进制编码的XML数据,但是会在Stream里为元素name和XML namespaces替换掉单个字节。

注释:我的看法,这种压缩的有很大的好处。在分布式计算力,性能的一个主要方面就是传输数据的大小。通常来说,更小数据传输会带来高效率的系统。把这个与消息应用关联起来,就是更小的消息意味着更小的数据传输,也就意味着更高的应用程序效率。代表性地,开发者和架构师过去经常考虑文本编码的XML,SOAP消息依赖数据传输因此性能很差。使用WCF以后,就会产生更紧凑的XML数据,很重要的是要指出讨论过二进制编码是不存在的,因为WCF可以产生很紧凑的XML数据。另外要重点指出的是讨论过的二进制编码不会与其它平台交互。希望日后,行业可以采纳标准的二进制编码。

现在我们已经看了如何实例化一个XmlDictionaryWriter对象并写XML数据到Stream里,那么我们再来看一下如何使用XmlDictionaryReader从Stream读取XML数据。

【老徐备注】

1. Big Endian和Little Endian:

在设计计算机系统的时候,有两种处理内存中数据的方法。一种叫为little-endian,存放在内存中最低位的数值是来自数据的最右边部分(也就是数据的最低位部分)。另一种称为big-endian,正好相反,存放在内存中最低位的数值是来自数据的最左边边部分(也就是数据的最高为部分)。

2. XmlDictionary:

实现用于优化 Windows Communication Foundation (WCF) XML 读取器/编写器实现的字典。

字典在常见文本字符串和整数之间建立映射,并为压缩和解压缩 XML 提供一种有效的机制。Windows Communication Foundation (WCF) 使用静态和动态 2 种字典。

使用静态字典时,通信的两端都使用预定义的字典。

使用动态字典时,发送端可以添加其映射不在静态字典中的新字符串。动态字典与消息一起在带外发送。动态字典使用 XmlBinaryWriterSession XmlBinaryReaderSession 类传输消息和映射。

参考:http://msdn.microsoft.com/zh-cn/library/system.xml.xmldictionary.aspx 

 

你可能感兴趣的:(SOA,and,EAI,《WCF技术内幕》翻译,wcf,stream,dictionary,xml,namespaces,encoding)