彻底弄懂文件和二进制数据的操作

  • Blob Blob 对象表示一个不可变、原始数据的类文件对象。Blob 表示的不一定是JavaScript原生格式的数据。File 接口基于Blob,继承了 blob 的功能并将其扩展使其支持用户系统上的文件。

    要从其他非blob对象和数据构造一个Blob,请使用 Blob() 构造函数。要创建包含另一个blob数据的子集blob,请使用 slice()方法。要获取用户文件系统上的文件对应的Blob对象,请参阅 File文档。

  • FileList  这个对象通常来自于一个HTML input元素的files属性,你可以通过这个对象访问到用户所选择的文件
  • File  接口提供有关文件的信息,并允许网页中的 JavaScript 访问其内容。
  • FileReader  FileReader 对象允许Web应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 FileBlob 对象指定要读取的文件或数据。

    其中File对象可以是来自用户在一个<input>元素上选择文件后返回的FileList对象,也可以来自拖放操作生成的 DataTransfer对象,还可以是来自在一个HTMLCanvasElement上执行mozGetAsFile()方法后返回结果。

  • URL  (ie浏览器不支持)

1.Blob 对象

Blob(Binary Large Object)对象代表了一段二进制数据。其它操作二进制数据的接口都是建立在此对象的基础之上。

生产Blob对象的方法:1.使用Blob 构造函数,2.对已有的Blob对象slice方法切割成小部分,应用场景有:大文件的断点续传。

(1)Blob 构造函数接收两个参数。第一个参数是数组,第二个参数是对象。这两个参数都是非必须的。

let blob = new Blob(["Hello World"],{ "type" : "text\/xml" });
let a = document.createElement("a");
a.href = window.URL.createObjectURL(blob);
a.download = "hello-world.txt";
a.textContent = "点击我,可以生产一个hello-word.txt的文件";
document.body.appendChild(a);复制代码

(2)Blob对象的slice方法,用来切割生成多个新的Blob对象。

document.querySelector('input[type="file"]').addEventListener('change', function(e) {
  let blob = this.files[0];  //通过此方法获取的数据为二进制数据

  const BYTES_PER_CHUNK = 1024 * 1024; // 定义切割单元1M
  const TOTLE_SIZE = blob.size;  //文件的总大小

  let start = 0;
  let end = BYTES_PER_CHUNK;

  while(start < TOTLE_SIZE ) {   //将 blob.slice(start, end) 作为数据,分割上传文件到服务器,再由服务端把分离的二进制数据合并为一个完整的数据
    // 注意:ajax中,xhr.responseType  设置为blob,那么服务器接收的就是二进制数据。
    // 在上传过程中,如果断网,断电,或者用户刷新啦页面,可能有部分未上传成功的二进制小块。那个下次上传的时候
    // 就可以只上传未上传成功的部分资源。当然这需要服务器端的配合。    start = end;
    end = start + BYTES_PER_CHUNK;
  }
}, false);复制代码

2.FileList对象

FileList对象针对<input type='file' multiple />标签。当用户通过<input type='file' multiple/>标签选取文件后,这个标签的files属性值就是FileList对象。它在结构上类似于数组,包含用户选取的多个文件。

<input type="file" id="input" onchange="console.log(this.files)" multiple />
//选择了两个文件后,控制台可以看到FileList对象中有两个File,分别是选择文件的二进制数据。
复制代码


                                   图1-1  File打印结果

现在的用户比较懒,往往喜欢拖拉拽的方式。使用拖拉拽的方式也可以得到FileList,可以就方便用户上传文件了。

let dropZone = document.getElementById('body');
dropZone.addEventListener('drop', handleFileSelect, false);
//防止把文件拖入网页时,资源以url的形式打开。
dropZone.ondragover = function () { return false; };
function handleFileSelect(evt) {
    evt.stopPropagation();
    evt.preventDefault();

    let files = evt.dataTransfer.files; // 里面包含了拖放的文件。
    console.log(files )    
}复制代码

3.File API

File API提供File对象,它是FileList对象的成员,包含了文件的一些元信息,比如文件名、上次改动时间、文件大小和文件类型。(如图1-1)

4.FileReader API

FileReader API用于读取文件,即把文件内容读入内存。它的参数是File对象或Blob对象。

对于不同类型的文件,FileReader提供不同的方法读取文件。

  • readAsBinaryString(Blob|File):返回二进制字符串,该字符串每个字节包含一个0到255之间的整数。(此方法已经废弃,官方推荐使用readAsArrayBuffer() )
  • readAsText(Blob|File, opt_encoding):返回文本字符串。默认情况下,文本编码格式是’UTF-8’,可以通过可选的格式参数,指定其他编码格式的文本(可以获取本地.txt ,.bat等文件内容,读取word,excell会乱码)。
  • readAsDataURL(Blob|File):返回一个基于Base64编码的data-url对象。
  • readAsArrayBuffer(Blob|File):返回一个ArrayBuffer对象。

FileReader对象采用异步方式读取文件,可以为一系列事件指定回调函数。

  • onabort方法:读取中断或调用reader.abort()方法时触发。
  • onerror方法:读取出错时触发。
  • onload方法:读取成功后触发。
  • onloadend方法:读取完成后触发,不管是否成功。触发顺序排在 onload 或 onerror 后面。
  • onloadstart方法:读取将要开始时触发。
  • onprogress方法:读取过程中周期性触发
网页获取.txt , .bat 文本内容
let reader = new FileReader();
reader.onload = function(e) {
  //console.log(e.target.result);
console.log(this.result);}
reader.readAsText(blob);复制代码

5.URL对象

URL对象用于生成指向File对象或Blob对象的URL。

let objecturl =  URL.createObjectURL(object);  //object File对象、Blob对象、MediaSource对象。​
img.src = objecturl   //跟readFile 对象差不多。同样可以展示图片在网页上

//window.URL.revokeObjectURL(objecturl);  //让url对象失效复制代码

上面的代码会对二进制数据生成一个URL,类似于“blob:http%3A//test.com/2342e6730-f45c-47c1-8012-ccc706f17192”。这个URL可以放置于任何通常可以放置URL的地方,比如img标签的src属性。需要注意的是,即使是同样的二进制数据,每调用一次URL.createObjectURL方法,就会得到一个不一样的URL。

这个URL的存在时间,等同于网页的存在时间,一旦网页刷新或卸载,这个URL就失效。除此之外,也可以手动调用URL.revokeObjectURL方法,使URL失效。

参考:

www.w3.org/TR/FileAPI/

developer.mozilla.org/zh-CN/docs/…

developer.mozilla.org/zh-CN/docs/…

developer.mozilla.org/zh-CN/docs/…

developer.mozilla.org/zh-CN/docs/…

javascript标准参考教程(alpha)

developer.mozilla.org/zh-CN/docs/…

developer.mozilla.org/zh-CN/docs/…