百度文库技术浅析

     最近上网总是有人问我百度文库技术或者是flex paper技术。呵呵。其实这个东西没有想的那么难。就百度文库来说,可以证明无论是adobe的 flash paper还是开源 的flash2print都没有做到那么智能。为什么说智能呢?你分析下你ie里的百度文库里缓存的 swf 文件 。会发现每个swf文件都是由几个swf拼接而成的,每一个cws就是一个swf文件。而且在文件的开始会有一个{"totalPage":"210","fromPage":"  1","toPage":"  6"}字段。这个可以当成Json也可以理解成AS3的对象。当然要想使用它,首先你需要对他进行序列化。 
totalPage  是说本文章的总页数。
fromPage  是从多少页来的。
toPage    是要到多少页去。
当然我们没有能力自己 开发 那样一个软件,那么就 使用 开源的flash2Print请求的时候要考虑到用户的体验所以在服务端生成swf文件的时候,一般都会选择拼页来实现。
那么请求第一页的时候,服务端发过来的 数据 是这样的,1-6页,为什么是1-6页呢,因为万恶的中国的带宽。呵呵。那么第二页的数据就是2-7页。
那么对应的请求:

Page  id                 页码

   1                      1-6
   2                      2-7
   .                       .
   .                       .
   10                     6-15
那么这是一个非常简单的规律,因为要考虑用户的跳页所以我们要去用户发送页码的前四页和后五页,这么做完全是为了是用户能更好的去体验并且减少服务端的压力。
那么后台调用并发送这些数据,我们在前端就 好办了。哈哈,写一个 播放器 就可以了那么首先我们要考虑一个问题就是, loader对就是loader,不能用常规的loader,因为返回的的是2进制文件,所以我们不能用display包里的 Loader 去解析了.因为他不是正常的swf,原因是这个2进制文件的开始还加了一个自定义对象需要我们去解析呢.
那么请问先生?你说不能用Loader对像,那你用什么呢?URLStream?URLLoader?,随你所好,用什么都行。URLLoader最简单了。哈哈。你可以用。关于这些加2进制的方法其实也就是相当于把数据 进行提炼,然后让AVM认识你,这样就可以播放了。不过我记得那时候我做的时候写的非常愚蠢。哈哈。也没有怎么弄明白就提笔就写,结果效率大打折扣。 源码 如下:谢绝效尤,不想到最后程序 效率低的话你也可以这么写哈哈 。
package com.loader
{
    /**
     *      加载 SWF文件 操作的 类 。
     *      提供一系列方法将拼接好的swf截取成byteArray类型数据然后
     *      分发给Ascode对象。
     */

    import com.display.DisplayLoader;
    import com.events.ItemLoadEvent;
    import com.events.SWFInfoComplelateEvent;
    import com.vo.pdfVO;
    import flash.events.EventDispatcher;
    public class SWFLoader extends EventDispatcher
    {     
       import flash.display.Loader;
       import flash.display.Sprite;
       import flash.events.Event;
       import flash.net.URLRequest;
       import flash.net.URLStream;
       import flash.utils.ByteArray;
       import com.events.SWFInfoComplelateEvent;
       import com.vo.pdfVO;


       public function SWFLoader()
       {
           addEventListener(SWFInfoComplelateEvent.LOAD_COMPLELATE_DATES,onCompleteHandler);
       }

       /**
        *  加载完成
        *  然后用vo对象对其序列化
        * 
        */

       public var  vo:pdfVO;
       private function onCompleteHandler(e:SWFInfoComplelateEvent):void
       {                             e.target.removeEventListener(SWFInfoComplelateEvent.LOAD_COMPLELATE_DATES,onCompleteHandler);
             vo=new pdfVO(e.obj.parent);
           var leng:Number=e.obj.position.length-1;
           for(var i :int=0; i<leng;i++)
           {
              var  byteArray:ByteArray=e.target.getStreamPostionDatas(e.obj.parent,e.obj.position.start,e.obj.position.end);
              var ds isplayLoader=new DisplayLoader(byteArray);
              boxes.push(ds);            
           }
           if(boxes[0]!=null) this.dispatchEvent(new ItemLoadEvent(ItemLoadEvent.ITEM_OK,boxes));
           return;
       }

       /**
        *   加载方法
        *  
        */

       private var path:URLRequest;
       public function load(source:String):void
       {
              if(stream) close() ;
              stream=new URLStream();
              path=new URLRequest(source);
              try
              {
                  stream.load(path);
              }
              catch(e:Error)
              {
                  trace("error");
              }
              stream.addEventListener(Event.COMPLETE, completeHandler);
       }

           /**
            *   获得index位置上的DisplayLoader对象
           */

       private  var boxes:Array=[];
       public function getDisplayyitemAt(index:int) isplayLoader
       {
           if(boxes[index]==undefined) return null;
           return boxes[index];
       }

           /**
           *      流加载完成
           */
        private  var  swfInfoBox:Array=[];
       private function completeHandler(e:Event):void
       {
               stream.removeEventListener(Event.COMPLETE, completeHandler);
              var arr:ByteArray=new ByteArray();
              stream.readBytes(arr,0,stream.bytesAvailable);
              var arrspeed:ByteArray=arr;
              swfInfoBox=SplitSWFInfo(arr);
              var obj:Object={
              stream:stream,
              parent:arr,
              alsoByte:arrspeed,
              position:swfInfoBox
              }
              var evt:SWFInfoComplelateEvent=new SWFInfoComplelateEvent("done",obj);
              this.dispatchEvent(evt);
       }         

       private var stream:URLStream;

       /**
        * 获得某一段数据
        */
       public function getStreamPostionDatas(source:ByteArray,index:Number,end:Number):ByteArray
       {
           var temp:ByteArray=new ByteArray();
           var j:Number=index;
           var length:Number=end-index;
           while(j<=end)
           {
                  temp[j-index]=source[j];
                  j++;
           }   

           return temp;
       }

       /**
        *  获得定点信息
        */
       public function getSWFpostionCollection(parent:ByteArray):Array
       {
           var swfInfoBox:Array=SplitSWFInfo(parent);
           return swfInfoBox;
       }

       /**
        *  截取swf信息(数据)
        *
        */
       public function  SplitSWFInfo(parent:ByteArray):Array
       {
           var leng:Number=parent.length;
           var endIndex:Array=[];
           var startIndex:Array=[];
           for(var i:Number=0;i<=leng;i++)
           {
              if(parent ==0x43&&parent[i+1]==0x57&&parent[i+2]==0x53)
              {
                  startIndex.push(i);
                  endIndex.push(i-1);
              }
           }
           var swfBox:Array=[];
           var len:Number=startIndex.length;
           for(var j:int=0;j<=len;j++ )
           {  
              j==len-1?swfBox[j]={start:startIndex[j],end:leng}:
                         swfBox[j]={start:startIndex[j],end:endIndex[j+1]};  
           }
           return swfBox;
       }

       /**
        *  关闭方法
        */
       public function close():void
       {
           stream.close();
           stream=null;
       }
    }
}

其实不用那么写,费半天劲呵呵就是为了加载数据.当时可能是用flash  IDE写的.所以写的很乱.现在想想出力不讨好了.使用 URLLoader就 不一样了。省力多了,不过一定要注意设置数据格式loader.dataFormat = URLLoaderDataFormat.BINARY;然后读经来以后,去找这个文件里有几个cws字符.然后分割swf数据.最后把分割后的数据放在一个数据集合或者是一个大数组, 最后用一个Loader  去显示他们。

你可能感兴趣的:(百度文库技术浅析)