zoukankan      html  css  js  c++  java
  • AMF序列化技巧

      AMF主要是在存储配置上很牛,但是还有很多小技巧可以让它更好。今天此文就是告诉你如何自定义对象的序列化和解序列化来让文件更小并且获得最大的控制。
          AMF格式产生的文件比JSONXML格式的都要小的多,但它主要不是因为减小文件大小而出名。AMF在一般对象上处理的还是不错的,但是很多情况我们需要关于特殊对象的具体信息。例如:一个元素的类Element

    1 class Element
    2 {
    3          public var symbol:String;
    4          public var atomicNumber:uint;
    5 }

     很不幸的是AS3不允许我们使用小整型, 32位足够元素数量的范围(0-119)。即使考虑新发现的元素,一个字节就可以处理0-255的范围并提供足够的增长空间。
           虽然AS3不提供小整型,我们可以在Bytearray或者IDataOutPut里存储小的整数值。我们可以使用任何类来实现flash.utiles.IExternalizable接口和自定义任何类的序列化。我们不需要依赖AMF默认的序列化操作,相反我们可以提供一个public function writeExternal(out:IDataOutput):void函数来写入任何数据,一个public function readExternal(in:IDataInput):void函数来读入任何需要解序列化的数据。
           这样我们就有一个很方便的方式来自定义任何类的序列化格式并仍然可以使用AMFByteArray.writeObject/readObject。当然我们不需要自定义所有的类,只定义我们选择的即可。而你的类的大小跟默认AMF格式的也差不多,但是当你想优化的时候只需要自定义一个或两个需要的类即可。
           Element类中,我们自定义了方式,这样只会在序列化元素数值这少量的字节。

     1 class ElementIEByte implements IExternalizable
     2 {
     3 public var symbol:String;
     4 public var atomicNumber:uint;
     5 
     6 public function writeExternal(output:IDataOutput): void
     7 {
     8 output.writeUTF(symbol);
     9 output.writeByte(atomicNumber);
    10 }
    11 
    12 public function readExternal(input:IDataInput): void
    13 {
    14 symbol = input.readUTF();
    15 atomicNumber = input.readUnsignedByte();
    16 }
    17 }

    理论上这可以为每个序列化的Element节省三个字节。来测试下,然后在另一个版本里使用IExternalizable并写全32为的整型值。

      1 package
      2 {
      3 import flash.net.registerClassAlias;
      4 import flash.utils.ByteArray;
      5 import flash.display.*;
      6 import flash.text.*;
      7 
      8 public class TestIExternalizable extends Sprite
      9 {
     10 private var __logger:TextField = new TextField();
     11 private function row(...cols): void
     12 {
     13 __logger.appendText(cols.join(",")+"\n");
     14 }
     15 
     16 public function TestIExternalizable()
     17 {
     18 stage.align = StageAlign.TOP_LEFT;
     19 stage.scaleMode = StageScaleMode.NO_SCALE;
     20 
     21 __logger.autoSize = TextFieldAutoSize.LEFT;
     22 addChild(__logger);
     23 
     24 row("Serializing to check size...");
     25 row();
     26 row("Class", "Size");
     27 
     28 registerClassAlias("ElementNormal", Element);
     29 registerClassAlias("ElementIExByt", ElementIEByte);
     30 registerClassAlias("ElementIExInt", ElementIEInt);
     31 
     32 var elem:Element = new Element();
     33 elem.symbol = "H";
     34 elem.atomicNumber = 1;
     35 var bytesElement:ByteArray = new ByteArray();
     36 bytesElement.writeObject(elem);
     37 row("Element size", bytesElement.length);
     38 
     39 var elemIEInt:ElementIEInt = new ElementIEInt();
     40 elemIEInt.symbol = "H";
     41 elemIEInt.atomicNumber = 1;
     42 var bytesElemInt:ByteArray = new ByteArray();
     43 bytesElemInt.writeObject(elemIEInt);
     44 row("ElementIEInt size", bytesElemInt.length);
     45 
     46 var elemIEByte:ElementIEByte = new ElementIEByte();
     47 elemIEByte.symbol = "H";
     48 elemIEByte.atomicNumber = 1;
     49 var bytesElemByte:ByteArray = new ByteArray();
     50 bytesElemByte.writeObject(elemIEByte);
     51 row("ElementIEByte size", bytesElemByte.length);
     52 
     53 row();
     54 row("Deserializing to check integrity...");
     55 row();
     56 
     57 bytesElement.position = 0;
     58 var elemCheck:Element = bytesElement.readObject() as Element;
     59 row(
     60 "Element",
     61 (elem.symbol == elemCheck.symbol
     62 && elem.atomicNumber == elemCheck.atomicNumber)
     63 ? "pass"
     64 : "fail"
     65 );
     66 
     67 bytesElemInt.position = 0;
     68 var elemIntCheck:ElementIEInt = bytesElemInt.readObject() as ElementIEInt;
     69 row(
     70 "ElementIEInt",
     71 (elemIEInt.symbol == elemIntCheck.symbol
     72 && elemIEInt.atomicNumber == elemIntCheck.atomicNumber)
     73 ? "pass"
     74 : "fail"
     75 );
     76 
     77 bytesElemByte.position = 0;
     78 var elemByteCheck:ElementIEByte = bytesElemByte.readObject() as ElementIEByte;
     79 row(
     80 "ElementIEByte",
     81 (elemIEByte.symbol == elemByteCheck.symbol
     82 && elemIEByte.atomicNumber == elemByteCheck.atomicNumber)
     83 ? "pass"
     84 : "fail"
     85 );
     86 }
     87 }
     88 }
     89 import flash.utils.IDataInput;
     90 import flash.utils.IDataOutput;
     91 import flash.utils.IExternalizable;
     92 
     93 class Element
     94 {
     95 public var symbol:String;
     96 public var atomicNumber:uint;
     97 }
     98 
     99 class ElementIEInt implements IExternalizable
    100 {
    101 public var symbol:String;
    102 public var atomicNumber:uint;
    103 
    104 public function writeExternal(output:IDataOutput): void
    105 {
    106 output.writeUTF(symbol);
    107 output.writeUnsignedInt(atomicNumber);
    108 }
    109 
    110 public function readExternal(input:IDataInput): void
    111 {
    112 symbol = input.readUTF();
    113 atomicNumber = input.readUnsignedInt();
    114 }
    115 }
    116 
    117 class ElementIEByte implements IExternalizable
    118 {
    119 public var symbol:String;
    120 public var atomicNumber:uint;
    121 
    122 public function writeExternal(output:IDataOutput): void
    123 {
    124 output.writeUTF(symbol);
    125 output.writeByte(atomicNumber);
    126 }
    127 
    128 public function readExternal(input:IDataInput): void
    129 {
    130 symbol = input.readUTF();
    131 atomicNumber = input.readUnsignedByte();
    132 }
    133 }

    在最后通过时所有的解序列化都会检查。下面是大小的比较结果:

     1 Class
     2 
     3 Size
     4 
     5 Element size
     6 
     7 41
     8 
     9 ElementIEInt size
    10 
    11 23
    12 
    13 ElementIEByte size
    14 
    15 20

    很明显,不使用默认的AMF序列化,直接写IDataOutput本身可以提供更小的文件大小。上图中,最后一个版本中使用字节而不是int,我们可以看到就像理论上预测的一样,我们介绍了额外的三个字节。
           总结下,如果你使用AMF来序列化类对象,并且想缩小文件大小,可以考虑使用IExternalizable来自定义序列化和解序列化处理过程。

    发现bug或者有什么疑问跟建议都可以评论哦!

    原文链接:http://jacksondunstan.com/articles/2248

  • 相关阅读:
    【JavaScript】关于javascript原型的深入理解
    【JavaScript】关于JS中的constructor与prototype
    【JavaScript】关于prototype
    【JavaScript】重温Javascript继承机制
    【JavaScript】新浪微博ajax请求后改变地址栏url,但页面不跳转的方案解析
    【JavaScript】JavaScript函数的参数
    【JavaScript】页面加载性能优化
    HTML5 修改浏览器url而不刷新页面
    【339】matplotlib based on python3
    【338】Pandas.DataFrame
  • 原文地址:https://www.cnblogs.com/atong/p/3096772.html
Copyright © 2011-2022 走看看