HTML5新特性之文件和二进制数据的操作
历史上,JavaScript无法处理二进制数据。如果一定要处理的话,只能使用charCodeAt()方法,一个个字节地从文字编码转成二进制数据,还有一种办法是将二进制数据转成Base64编码,再进行处理。这两种方法不仅速度慢,而且容易出错。ECMAScript5引入了Blob对象,允许直接操作二进制数据。
Bolb对象是一个代表二进制数据的基本对象,在它的基础上,又衍生出一系列相关的API,用来操作文件。
- File对象:负责处理那些以文件形式存在的二进制数据,也就是操作本地文件
- FileList对象:File对象的网页表单接口
- FileReader对象:负责将二进制数据读入内存
- URL对象:用于对二进制数据生成URL
1、Blob对象
Blob(Binary Large Object)对象代表了一段二进制数据,提供了一系列操作接口。其他操作二进制数据的API(比如File对象),都是建立在Blob对象基础上的,继承了它的属性和方法。
生成Blob对象有两种方法:一种是使用Blob构造函数,另一种是对现有的Blob对象使用slice方法切出一部分。
(1)Blob构造函数,接受两个参数。第一个参数是一个包含实际数据的数组,第二个参数是数据的类型,这两个参数都不是必需的。
var htmlParts = ['<a id="a"><b id="b">hey!<\/b><\/a>'];
var myBlob = new Blob(htmlParts, {'type': 'text\/xml'});
下面是一个利用Blob对象,生成可下载文件的例子。
var blob = new Blob(['Hello World']);
var a = document.createElement('a');
a.href = window.URL.createObjectURL(blob);
a.donwload = 'hello-world.txt';
a.textContent = 'Download Hello World';
body.appendChild(a);
上面的代码生成了一个超级链接,点击后提示下载文本文件hello-world.txt,文件内容为"Hello World"。
(2) Blob对象的slice方法,将二进制数据按照字节分块,返回一个新的Blob对象。
var newBlob = oldBlob.slice(startingByte, endindByte);
下面是一个使用XMLHttpRequest对象,将大文件分割上传的例子。
function upload(blobOrFile) {
var xhr = new XMLHttpRequest();
xhr.open('POST', '/server', true);
xhr.onload = function(e) { ... };
xhr.send(blobOrFile);
}
document.querySelector('input[type="file"]').addEventListener('change', function(e) {
var blob = this.files[0];
var BYTES_PER_CHUNK = 1024 * 1024; // 1MB chunk sizes.
var SIZE = blob.size;
var start = 0;
var end = BYTES_PER_CHUNK;
while(start < SIZE) {
upload(blob.slice(start, end));
start = end;
end = start + BYTES_PER_CHUNK;
}
}, false);
(3)Blob对象有两个只读属性:
- size:二进制数据的大小,单位为字节。
- type:二进制数据的MIME类型,全部为小写,如果类型未知,则该值为空字符串。
在Ajax操作中,如果xhr.responseType设为blob,接收的就是二进制数据。
2、FileList对象
FileList对象针对表单的File控件。当用户通过file控件选取文件后,这个控件的files属性值就是FileList对象。它在结构上类似于数组,包含用户选取的多个文件。
<input type="file" id="input" onchange="console.log(this.files.length)" multiple />
当用户选取文件后,就可以读取该文件。
var selected_file = document.getElementById('input').files[0];
采用拖放方式,也可以得到FileList对象。
var dropZone = document.getElementById('drop_zone');
dropZone.addEventListener('drop', handleFileSelect, false);
function handleFileSelect(evt) {
evt.stopPropagation();
evt.preventDefault();
var files = evt.dataTransfer.files; // FileList object.
// ...
}
上面代码的 handleFileSelect 是拖放事件的回调函数,它的参数evt是一个事件对象,该参数的dataTransfer.files属性就是一个FileList对象,里面包含了拖放的文件。
3、File对象
File对象是FileList对象的成员,包含了文件的一些元信息,比如文件名、上次改动时间、文件大小和文件类型。它的属性值如下:
- name:文件名,该属性只读
- size:文件大小,单位为字节,该属性只读
- type:文件的MIME类型,如果分辨不出类型,则为空字符串,该属性只读。
- lastModifiedDate:文件的上次修改时间,该属性只读。
var selected_file = document.getElementById('input').files[0];
var fileName = selected_file.name;
var fileSize = selected_file.size;
var fileType = selected_file.type;
4、FileReader 对象
FileReader对象接收File对象或Blob对象作为参数,用于读取文件的实际内容,即把文件内容读入内存。对于不同类型的文件,FileReader使用不同的方法读取。
- FileReader.readAsBinaryString(Blob|File) :读取结果为二进制字符串,每个字节包含一个0到255之间的整数。
- FileReader.readAsText(Blob|File, opt_encoding) :读取结果是一个文本字符串。默认情况下,文本编码格式是'UTF-8',可以通过可选的格式参数,指定其他编码格式的文本。
- FileReader.readAsDataURL(Blob|File) : 读取结果是一个基于Base64编码的 data-uri 对象。
- FileReader.readAsArrayBuffer(Blob|File) :读取结果是一个 ArrayBuffer 对象。
FileReader采用异步方式读取文件,可以为一系列事件指定回调函数。
- onabort:读取中断或调用reader.abort()方法时触发。
- onerror:读取出错时触发。
- onload:读取成功后触发。
- onloadend:读取完成后触发,不管是否成功。触发顺序排在 onload 或 onerror 后面。
- onloadstart:读取将要开始时触发。
- onprogress:读取过程中周期性触发。
下面的代码是如何展示文本文件的内容。
var reader = new FileReader();
reader.onload = function(e){
console.log(e.target.result);
}
reader.readAsText(blob);
onload事件的回调函数接受一个事件对象,该对象的target.result就是文件的内容。
下面是一个使用readAsDataURL方法,为img元素添加src属性的例子。
var reader = new FileReader();
reader.onload = function(e) {
document.createElement('img').src = e.target.result;
};
reader.readAsDataURL(f);
下面是一个onerror事件回调函数的例子。
var reader = new FileReader();
reader.onerror = errorHandler; function errorHandler(evt) {
switch(evt.target.error.code) {
case evt.target.error.NOT_FOUND_ERR:
alert('File Not Found!');
break;
case evt.target.error.NOT_READABLE_ERR:
alert('File is not readable');
break;
case evt.target.error.ABORT_ERR:
break;
default:
alert('An error occurred reading this file.');
};
}
下面是一个onprogress事件回调函数的例子,主要用来显示读取进度。
var reader = new FileReader();
reader.onprogress = updateProgress; function updateProgress(evt) {
if (evt.lengthComputable) {
var percentLoaded = Math.round((evt.loaded / evt.totalEric Bidelman) * 100); var progress = document.querySelector('.percent');
if (percentLoaded < 100) {
progress.style.width = percentLoaded + '%';
progress.textContent = percentLoaded + '%';
}
}
}
读取大文件的时候,可以利用Blob对象的slice方法,将大文件分成小段,逐一读取,这样可以加快处理速度。
5、URL对象
URL对象用于生成指向File对象或Blob对象的URL。
var objecturl = window.URL.createObjectURL(blob);
上面的代码会对二进制数据生成一个URL,类似于“blob:http%3A//test.com/666e6730-f45c-47c1-8012-ccc706f17191”。这个URL可以放置于任何通常可以放置URL的地方,比如img标签的src属性。需要注意的是,即使是同样的二进制数据,每调用一次URL.createObjectURL方法,就会得到一个不一样的URL。
这个URL的存在时间,等同于网页的存在时间,一旦网页刷新或卸载,这个URL就失效。除此之外,也可以手动调用URL.revokeObjectURL方法,使URL失效。
window.URL.revokeObjectURL(objectURL);
下面是一个利用URL对象,在网页插入图片的例子。
var img = document.createElement("img");
img.src = window.URL.createObjectURL(files[0]);
img.height = 60;
img.onload = function(e) {
window.URL.revokeObjectURL(this.src);
}
body.appendChild(img);
var info = document.createElement("span");
info.innerHTML = files[i].name + ": " + files[i].size + " bytes";
body.appendChild(info);
还有一个本机视频预览的例子。
var video = document.getElementById('video');
var obj_url = window.URL.createObjectURL(blob);
video.src = obj_url;
video.play()
window.URL.revokeObjectURL(obj_url);
6、参考链接
[2] Andrew Dodson, Get Loaded with the File API
[3] Mozilla Developer Network, Using files from web applications
[5] Eric Bidelman, Reading files in JavaScript using the File APIS
注:本文转自http://javascript.ruanyifeng.com/htmlapi/file.html,有修改。
HTML5新特性之文件和二进制数据的操作的更多相关文章
- HTML5新特性之文件和二进制数据的操作 Blob对象
HTML5新特性之文件和二进制数据的操作 1.Blob对象 2.FileList对象 3.File对象 4.FileReader 对象 5.URL对象
- web全栈架构师[笔记] — 03 html5新特性
HTML5新特性 一.geolocation PC端 精度比较低 通过IP库定位 移动端 通过GPS window.navigator.geolocation 单次 getCurrentPositio ...
- 第二季第八天 HTML5新特性
在函数内部window.a = a 在全局中就可以拿到这个变量 变量命名.作为函数的参数的时候要详细.调用的时候可以简单点 做全局变量的两个方案 1.绑在标签上data 2.闭包 视频一般都是二进 ...
- 前端进阶系列(三):HTML5新特性
HTML5 是对 HTML 标准的第五次修订.其主要的目标是将互联网语义化,以便更好地被人类和机器阅读,并同时提供更好地支持各种媒体的嵌入.HTML5 的语法是向后兼容的.现在国内普遍说的 H5 是包 ...
- HTML5新特性 websocket(重点)--多对多聊天室
一.html5新特性 websocket(重点)--多对多聊天室 HTTP:超文本传输协议 HTTP作用:传输网页中资源(html;css;js;image;video;..) HTTP是浏览器搬运 ...
- HTML5新特性--svg-echarts(重点)-拖动API-WebWorker
一.html5新特性--svg--(折线/渐变特效对象/滤镜) #折线:多个坐标点组件一条折线 <polyline points="50,50 70,55 60,66 " s ...
- html5新特性
这一篇博文不会告诉你怎么去使用html5的新特性,只会给你总结一下新特性------对于好学的人可以把这篇文章当做一个目录 对于初接触的人来说是一个导向 对于已经接触过的人来说是一个检测你掌握程度的检 ...
- 转: HTML5新特性之Mutation Observer
转: HTML5新特性之Mutation Observer Mutation Observer是什么 Mutation Observer(变动观察器)是监视DOM变动的接口.当DOM对象树发生任何变动 ...
- html5新特性与用法大全了解一下
有好多小伙伴私聊我问我html5新特性 和用法,下面我给大家具体介绍一下html5都新加了哪些新特性,下面我给大家总结一下. 1)新的语义标签 footer header 等等2)增强型表单 表单2. ...
随机推荐
- MVC5为WebAPI添加命名空间的支持1
前言 默认情况下,微软提供的MVC框架模板中,WebAPI路由是不支持Namespace参数的.这导致一些比较大型的项目,无法把WebApi分离到单独的类库中. 本文将提供解决该问题的方案. 微软官方 ...
- VS2015安装ASP.NET MVC4
http://www.microsoft.com/zh-cn/download/details.aspx?id=44533 下载安装 AspNetMVC4.msi
- 【转】Jenkins怎么启动和停止服务
笔者没有把Jenkins配置到tomcat中,每次都是用命令行来启动Jenkins.但是遇到一个问题:Jenkins一直是开着的,想关闭也关闭不了.百度了一些资料,均不靠谱(必须吐槽一下百度).于是进 ...
- C# 7 out variables, tuples & other new features
C# 7 out variables, tuples & other new features C# 7 is available on new Visual Studio 2017 and ...
- Screen2EXE录屏|录制视频
Screen2EXE是一款具有独到压缩算法的屏幕录制软件,它可以记录用户在屏幕上的每一步操作,包括鼠标轨迹,点击动作给予花环提示,然后保存为不需播放器即可观看的exe可执行文件. 在生成录制文件的大小 ...
- 深入浅出DOM基础——《DOM探索之基础详解篇》学习笔记
来源于:https://github.com/jawil/blog/issues/9 之前通过深入学习DOM的相关知识,看了慕课网DOM探索之基础详解篇这个视频(在最近看第三遍的时候,准备记录一点东西 ...
- 远程阿里云window服务器报错身份验证错误
整理文章,很久之前遇到的一个问题,一直呆在草稿箱,特发布出来,帮助可能遇到该问题的人 mstsc连接时报错如下 解决方法: 修改本地安全组策略[安全组 gpedit.msc]
- iOS App转让流程详情教程篇
最近对公司旗下两款app进行转让,正好记一下操作流程: 1.登录iTunes发布网站,找到app,查看App信息下方有个[转让 App] 按钮. 2.点进去,是如下界面,里面包含是否满足转让条件,理论 ...
- 【RS】Modeling User Exposure in Recommendation - 在推荐中建模用户的暴露程度
[论文标题]Modeling User Exposure in Recommendation (2016-WWW) [论文作者]Dawen Liang,Laurent Charlin,James Mc ...
- 解决flume运行中的一个异常问题!
今天在本地测试flume的exec 监控文件 分割的问题!!!遇到各种141异常问题! 怀疑是在切割文件的时候超过了监控文本的时间,导致flume异常退出,,,所以增加了keep-alive 时 ...