File和Blob对象详解
1. 基本概念
1.1 Blob对象
Blob(Binary Large Object)是表示二进制数据的对象,是JavaScript中处理二进制数据的基础类型。
定义:
- Blob对象表示一个不可变、原始数据的类文件对象
- 它的数据可以按文本或二进制的格式进行读取
- 也可以转换成ReadableStream来用于数据操作
构造方法:
new Blob(blobParts, options);
参数:
blobParts
:数组类型,可以存放任意个ArrayBuffer、ArrayBufferView、Blob或DOMString(会编码为utf-8)options
:可选,可以设置blob的type和endings
1.2 File对象
File对象是特殊类型的Blob,继承了Blob的功能并扩展了与文件系统相关的功能。
定义:
- File接口提供有关文件的信息,并允许网页中的JavaScript访问其内容
- File是Blob的子类,继承了Blob的所有属性和方法
获取File对象的方式:
- 通过
<input type="file">
元素的files属性 - 通过拖放操作的DataTransfer.files属性
- 通过构造函数
new File()
2. Blob与File的区别与联系
2.1 联系
- File是Blob的子类,继承了Blob的所有属性和方法
3 - 两者都可以用于处理二进制数据
- 都支持slice方法来获取数据的子集
2.2 区别
特性 | Blob | File |
---|---|---|
元数据 | 不包含文件元数据 | 包含文件名、修改日期等元数据 |
用途 | 通用二进制数据处理 | 专注于文件系统交互 |
创建方式 | 通过构造函数或Canvas等API | 通常从用户输入或拖放获取 |
属性 | size, type | name, lastModified, size, type |
3. Blob对象详解
3.1 属性
- size:Blob对象中所包含数据的大小(字节)
- type:Blob对象所包含数据的MIME类型,如果类型未知,则为空字符串
3.2 方法
- slice([start[, end[, contentType]]]):返回一个新的Blob对象,包含了源Blob对象中指定范围内的数据
- stream():返回一个ReadableStream,读取Blob内容
- text():返回一个Promise,完成后得到Blob内容的UTF-8格式字符串
- arrayBuffer():返回一个Promise,完成后得到一个ArrayBuffer表示的Blob数据
3.3 常见用途
- 生成和处理二进制数据
- 创建URL(通过URL.createObjectURL)
- 文件下载
- 图像处理
- 音视频处理
4. File对象详解
4.1 属性
- name:文件名,不包含路径
- size:文件大小(字节)
- type:文件的MIME类型
- lastModified:文件最后修改时间的时间戳(毫秒)
1
4.2 方法
File对象继承了Blob的所有方法,包括:
- slice()
- stream()
- text()
- arrayBuffer()
4.3 FileReader API
FileReader是一个用于读取File或Blob内容的API:
const reader = new FileReader();
// 读取完成事件
reader.onload = function(e) {
const content = e.target.result;
// 处理文件内容
};
// 读取文件
reader.readAsText(file); // 读取为文本
// 或
reader.readAsDataURL(file); // 读取为Data URL
// 或
reader.readAsArrayBuffer(file); // 读取为ArrayBuffer
5. 实际应用场景
5.1 文件上传
// 获取文件输入元素
const fileInput = document.querySelector('#fileInput');
// 监听change事件
fileInput.addEventListener('change', function(e) {
// 获取选择的文件列表
const files = e.target.files;
// 创建FormData对象
const formData = new FormData();
// 添加文件到FormData
for (let i = 0; i < files.length; i++) {
formData.append('file' + i, files[i]);
}
// 使用fetch API上传
fetch('/upload', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => console.log('上传成功:', data))
.catch(error => console.error('上传失败:', error));
});
5.2 图片预览
function previewImage(file) {
// 确保文件是图片
if (!file.type.match('image.*')) {
return;
}
const reader = new FileReader();
// 设置读取完成事件
reader.onload = function(e) {
const img = document.createElement('img');
img.src = e.target.result;
document.getElementById('preview').appendChild(img);
};
// 读取文件为Data URL
reader.readAsDataURL(file);
}
// 使用示例
document.querySelector('#imageInput').addEventListener('change', function(e) {
const files = e.target.files;
for (let i = 0; i < files.length; i++) {
previewImage(files[i]);
}
});
5.3 文件下载
function downloadFile(content, filename, contentType) {
// 创建Blob对象
const blob = new Blob([content], { type: contentType });
// 创建URL
const url = URL.createObjectURL(blob);
// 创建下载链接
const a = document.createElement('a');
a.href = url;
a.download = filename;
// 模拟点击下载
document.body.appendChild(a);
a.click();
// 清理
document.body.removeChild(a);
URL.revokeObjectURL(url);
}
// 使用示例 - 下载JSON数据
const data = { name: 'example', value: 42 };
documentFile(JSON.stringify(data), 'data.json', 'application/json');
// 使用示例 - 下载文本
documentFile('Hello, World!', 'hello.txt', 'text/plain');
5.4 从URL创建Blob
async function fetchImageAsBlob(url) {
const response = await fetch(url);
const blob = await response.blob();
return blob;
}
// 使用示例
fetchImageAsBlob('https://example.com/image.jpg')
.then(blob => {
const img = document.createElement('img');
img.src = URL.createObjectURL(blob);
document.body.appendChild(img);
})
.catch(error => console.error('获取图片失败:', error));
5.5 Canvas转换为Blob
const canvas = document.querySelector('canvas');
canvas.toBlob(function(blob) {
// 使用生成的Blob
const url = URL.createObjectURL(blob);
const img = document.createElement('img');
img.src = url;
document.body.appendChild(img);
}, 'image/jpeg', 0.95); // JPEG格式,95%质量
6. 兼容性与注意事项
- Blob和File API在现代浏览器中得到了广泛支持
- 在处理大文件时,应考虑使用分片上传
- 使用完URL.createObjectURL()创建的URL后,应调用URL.revokeObjectURL()释放内存
- 在移动设备上处理大型Blob可能会导致性能问题
- 对于旧版浏览器,可能需要使用polyfill
7. 总结
Blob和File对象是Web前端处理二进制数据的强大工具:
- Blob是通用的二进制数据容器,适用于各种二进制数据处理场景
- File是Blob的特化版本,专注于文件操作,提供了额外的文件元数据
- 两者结合使用,可以实现文件上传、下载、预览等常见功能
- 通过FileReader、URL.createObjectURL等API,可以方便地读取和操作这些对象
在前端开发中,熟练掌握Blob和File对象的使用,对于处理用户上传、文件生成、媒体处理等场景至关重要。