【连接】

本文转自豆瓣社区http://www.douban.com/note/225494734/


1、http://www.html5rocks.com/en/tutorials/webgl/typed_arrays/
这篇写得比我好。

2、至于一些很方便库,可以直接看aurora.js这个项目,为了解析音频文件,这个项目下了很大功夫...

https://github.com/ofmlabs/aurora.js

【前言】
JS其实是众所周知的弱类型语言。所以一般来说不属于严肃编程领域,直到近年才受到关注,WEB 2.0以及很多新技术的兴起。把它抬上了严肃编程的范畴。

这里主要记录最近碰到的JS,学术一些来说应该说是EMSCRIPT标准、W3C、HTML5、GOOGLE推出的一系列,对这个语言库级别的改进。

对二进制的需求与日俱增的原因如下:WEBSCOKET的传输需求,FILE API对文件、二进制BLOB对象的处理,WEBGL对于大量二进制数据的需求,CAVANS对二进制的处理的迫切需求、XHR2对新的二进制对象的处理需求,也会叙述与NODE.JS的二进制有关的事宜。

*PS:强烈建议去阅读原草案,以及标准文档,当然这里会给出草案的地址

【目录】
一、XHR2
二、FILE API
       1、FILE LIST
       2、FILE
       3、FILEREADER
三、BLOB URL
四、TYPED ARRAY
      1、BUFFER
      2、ArrayView
      3、DataView
      4、Blob 与 arraybuffer
      5、arraybuffer 与 arraybufferView
五、WEBSCOKET
六、WEBGL

【XHR2】
http://www.html5rocks.com/en/tutorials/file/xhr2/
http://www.w3.org/TR/XMLHttpRequest/#the-responsetype-attribute

新的XHR2语法上有很多改进,细节部分不详述,可以参见草案。
//得到某个文件的串列
var getArrayBuffer=function(url){
                var resourceUrl = url || "http://img1.douban.com/pics/nav/lg_main_a10.png";
                var deferred = $.Deferred();
                var promise = deferred.promise();
            var xhr = new XMLHttpRequest();
            xhr.open('GET', resourceUrl, true);

            // Response type arraybuffer - XMLHttpRequest 2
            xhr.responseType = 'arraybuffer';
            xhr.onerror = function(e) {
                        deferred.reject(xhr, e);
        }

            xhr.onload = function(e) {
                if (xhr.status == 200) {
                    deferred.resolve(xhr);
                }
            };
            xhr.send();
            return promise;
        }
这里使用了JQ的defferd对象,可以无视,主要修改在于返回xhr.responseType可以设置成arraybuffer或者blob。

【FILE API】

1、主要有File List来表述任何<input type='file'>里的对象,File继承与Blob父类,对了长度以及文件名属性,继承了Slice操作。

2、File表述一个<input type=file>里的文件对象,注意,这里的File似乎必须是来自于用户输入,暂时没有找到凭空构造的方式。

3、Blob对象是File的父类,主要会感兴趣的操作为Slice,分割操作。

4、FileReader()读写类,主要负责File|Blob对象的读写
http://www.w3.org/TR/FileAPI/#readAsDataURL

var loadBlobToBase64=function(blob){
                var deferred = $.Deferred();
                var promise = deferred.promise();

                var reader = new FileReader();
                reader.onload = function() {
                          deferred.resolve(reader.result);
        }
               reader.readAsDataURL(blob);
               return promise;
}
比较有用的操作为将File或Blob对象读写成为BASE64编码的DataURL,readAsText(),以及readAsArrayBuffer()

【URL API/BLOB URI】
http://www.w3.org/TR/FileAPI/#url

这个理解起来较为简单,在标准里,也位于FILE API草案中描述。

var url=window.webkitURL.createObjectURL(blob);
console.log(url);

输出为:blob:xxxx-xxx-xxx--xxx#frament...

简单得说就是,你可以使用File API中的FileReader()类,将文件或二进制的大块Blob,readAsDataURL,然后赋予img src或其他。

也可以将blob转储为BLOB URL,官方的表述即ObjectURL

怎样理解?

这个URL,是一个内存级的指针,但可以供网页调用,其行为与普通的来自服务器的文件毫无二致。

有200状态码,也有500状态码,可以销毁。

【Typed Array】
http://www.khronos.org/registry/typedarray/specs/latest/

这是这整一套API的核心部分,事实上,不理解这部分,就很难对数据进行任何有效的操作与转换。

暂时以我的理解来说。

1、Buffer
http://www.khronos.org/registry/typedarray/specs/latest/#5
var a=new ArrayBuffer(8);
建立一个新的ArrayBuffer(8);,8bit位为一个单位,uint8。我要了8个单位,即字节。

这是一个内存级别的表达,一个buf.

2、View
http://www.khronos.org/registry/typedarray/specs/latest/#7
appendBuffer=function ( buffer1, buffer2 ) {
                  var tmp = new Uint8Array( buffer1.byteLength + buffer2.byteLength + 4);
                          tmp.set( new Uint8Array( buffer1 ), 0 );
                          tmp.set( new Uint8Array( buffer2 ), buffer1.byteLength );
                  return tmp;
        }

new Uint8Array实际上是建立了一个ref,指针。它可以指向一个已有的buf,那么这里新建了一个tem,其大小为两个buf之和+4.

第二句话是,从0偏移量开始,填入一个新的Typed ArrayView ,而这个指针是以buffer1初始化的。
第三句,是从刚才的结尾开始,填入buffer2的内容。

这里待修改。

3、DataView
http://www.khronos.org/registry/typedarray/specs/latest/#8
https://developer.mozilla.org/en/JavaScript_typed_arrays/DataView

暂略

4、Blob 与 arraybuffer
http://www.w3.org/TR/FileAPI/#dfn-BlobPropertyBag
著名的文章,构造BLOB,别BUILD,指之前一个非废止的API ,Blobuilder。那个方法效率很低,而且容易出错(我就写JS写出蓝屏...过....)

所以,正确的构造法为:

var blob = new Blob([new_buffer], { type: "image/png" });

传入一个ArrayBuffer对象,并给出MIME TYPE之后,就可以构造恰当的对象。

var url = window.webkitURL.createObjectURL(blob);

接着可以用刚才提到的方式,构造BLOB URL,以供<img src>来调用。

5、arraybuffer 与 arraybufferView
http://www.khronos.org/registry/typedarray/specs/latest/#6
这个当初也让我迷惑了一阵子,直到看到草案上的复杂数据结构的一个例子之后才理解了。

简单的说:
appendBuffer=function ( buffer1, buffer2 ) {
                  var tmp = new Uint8Array( buffer1.byteLength + buffer2.byteLength + 4);
                          tmp.set( new Uint8Array( buffer1 ), 0 );
                          tmp.set( new Uint8Array( buffer2 ), buffer1.byteLength );
                  return tmp;
        }

刚才的例子里,返回的这个tmp,实际上是一个arraybufferView对象,而非buffer本身。

在构造新的BLOB时发现的,所有的Uin8Array对象,都会有一个属性,即buffer属性。

要得到指针指的对象的内容,访问这个属性即可。
var blob = new Blob([tmp.buffer], { type: "image/png" });

如果你要操作tmp,并构造成BLOB对象,直接用arrayBuffer就可以了,如果传入的是一个TypedArrayView?,也不用着急,访问其.buffer属性即得到背后的ArrayBuffer属性。

 posted on 2012-09-10 18:36 落叶满长沙 阅读(...) 评论(...) 编辑 收藏