【连接】
本文转自豆瓣社区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属性。