JavaScript中的 File 和 Blob对象

前言

在 JavaScript 中,File 和 Blob 是 Web API 提供的两个重要对象,用于处理文件和二进制数据。它们被广泛应用于文件上传、下载、读取以及数据操作等场景。

blob

Blob 对象表示一个不可变的、原始数据的类文件对象。它提供了对文件内容的抽象,而不关心具体内容本身。你可以使用 Blob 来存储二进制数据。可以用来存储文件、图片、音频、视频、甚至是纯文本等各种类型的数据。Blob 提供了一种高效的方式来操作数据文件,而不需要将数据全部加载到内存中,这在处理大型文件或二进制数据时非常有用。

const blob = new Blob(blobParts, options);
blobParts: 一个数组,包含将被放入 Blob 对象中的数据,可以是字符串、数组缓冲区(ArrayBuffer)、TypedArray、Blob 对象等。
options: 一个可选的对象,可以设置 type(MIME 类型)和 endings(用于表示换行符)。
// 创建一个包含文本的 Blob
const textBlob = new Blob(["Hello, Blob!"], { type: "text/plain" });
console.log(textBlob); // Blob { size: 12, type: "text/plain" }

// 创建一个包含二进制数据的 Blob
const binaryBlob = new Blob([new Uint8Array([72, 101, 108, 108, 111])], { type: "application/octet-stream" });
console.log(binaryBlob); // Blob { size: 5, type: "application/octet-stream" }

Blob 对象主要有以下几个属性:

	size: 返回 Blob 对象的大小(以字节为单位)。
		console.log(blob.size); // 输出 Blob 的大小
	type: 返回 Blob 对象的 MIME 类型。
		console.log(blob.type); // 输出 Blob 的 MIME 类型

Blob 对象提供了一些常用的方法来操作二进制数据。
1、slice([start], [end], [contentType])

该方法用于从 Blob 中提取一部分数据,并返回一个新的 Blob 对象。
参数 start 和 end 表示提取的字节范围,contentType 设置提取部分的 MIME 类型。
const blob = new Blob(["Hello, Blob!"], { type: "text/plain" });
const partialBlob = blob.slice(0, 5);

2、text()

该方法将 Blob 的内容读取为文本字符串。它返回一个 Promise,解析为文本数据。
blob.text().then((text) => {
  console.log(text); // 输出 "Hello, Blob!"
});

3、arrayBuffer()

该方法将 Blob 的内容读取为 ArrayBuffer 对象,适合处理二进制数据。它返回一个 Promise,解析为 ArrayBuffer 数据。
const blob = new Blob(["Hello, Blob!"], { type: "text/plain" });
blob.arrayBuffer().then((buffer) => {
  console.log(buffer);
});

在这里插入图片描述
ArrayBuffer 的实际应用:图片预览

const fileInput = document.querySelector('#fileInput');
fileInput.addEventListener('change', (event) => {
  const file = event.target.files[0];
  
  file.arrayBuffer().then((arrayBuffer) => {
    const blob = new Blob([arrayBuffer], { type: file.type });
    const objectURL = URL.createObjectURL(blob);
    
    const img = document.createElement('img');
    img.src = objectURL;
    document.body.appendChild(img);
    
    URL.revokeObjectURL(objectURL); // 释放资源
  });
});

4、stream()

stream() 是 Blob 对象的一个方法,用于将 Blob 的数据作为一个 ReadableStream 返回。这种方式允许以流的方式逐块读取数据,非常适合处理 大文件,避免一次性加载整个文件到内存中,节约资源。
const readableStream = blob.stream();
// 返回值: 一个 ReadableStream,用于逐步读取 Blob 的内容。
// 用途:
// 处理大文件的流式传输。
// 避免大文件占用大量内存。

示例1、使用 ReadableStream 读取数据块

const blob = new Blob(["Hello, World!"], { type: "text/plain" });

const reader = blob.stream().getReader(); // 获取流的 reader

reader.read().then(function process({ done, value }) {
  if (done) {
    console.log('Stream complete');
    return;
  }

  console.log(new TextDecoder().decode(value)); // 解码并打印每块数据
  return reader.read().then(process); // 继续读取下一块数据
});

示例2、流式上传文件

const uploadFile = async (file) => {
  const reader = file.stream().getReader();

  while (true) {
    const { done, value } = await reader.read();
    if (done) {
      console.log('File upload complete');
      break;
    }
    // 将每块数据上传到服务器
    await fetch('/upload', {
      method: 'POST',
      body: value,
    });
  }
};

const fileInput = document.querySelector('#fileInput');
fileInput.addEventListener('change', (event) => {
  const file = event.target.files[0];
  uploadFile(file);
});

Blob 的使用场景

1、生成文件下载
可以通过 Blob 创建文件并生成下载链接供用户下载文件

// 动态生成一个文本文件
const blob = new Blob(["Hello, World!"], { type: "text/plain" });
const url = URL.createObjectURL(blob);

const a = document.createElement('a');
a.href = url;
a.download = "example.txt"; // 文件名
document.body.appendChild(a);
a.click();
URL.revokeObjectURL(url); // 释放 URL 对象

2、上传文件
将用户上传的文件通过 Blob 或 FormData 传输到服务器。

const fileInput = document.querySelector('#fileInput');
fileInput.addEventListener('change', async (event) => {
  const file = event.target.files[0];
  const formData = new FormData();
  formData.append('file', file);

  const response = await fetch('/upload', {
    method: 'POST',
    body: formData,
  });
  console.log('File uploaded:', response.ok);
});

3、文件预览
用于在网页上显示用户上传的文件内容,比如图片、音频、视频或 PDF 文件。

// 1 文件预览图片
const input = document.querySelector('#fileInput');
input.addEventListener('change', (event) => {
  const file = event.target.files[0];
  const url = URL.createObjectURL(file);

  const img = document.createElement('img');
  img.src = url;
  document.body.appendChild(img);

  URL.revokeObjectURL(url); // 释放 URL
});

// 2 使用 Canvas 生成图片并保存为 Blob
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
ctx.fillStyle = 'blue';
ctx.fillRect(0, 0, 200, 200);

canvas.toBlob((blob) => {
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = 'canvas-image.png';
  a.click();
  URL.revokeObjectURL(url);
}, 'image/png');

4、CSV 或 Excel 数据生成

const data = [
  ["Name", "Age", "City"],
  ["Alice", "24", "New York"],
  ["Bob", "30", "San Francisco"],
];

const csvContent = data.map(row => row.join(',')).join('\n');
const blob = new Blob([csvContent], { type: 'text/csv' });

const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = "data.csv";
a.click();
URL.revokeObjectURL(url);

File

File 是 JavaScript 中代表文件的数据结构,是 Blob 的子类,包含文件的元数据(如文件名、文件大小、类型等)。File 对象通常由用户通过 选择文件时创建,也可以使用 JavaScript 构造函数手动创建。

new File(array, name, options);
// 创建一个 File 对象
const file = new File(["Hello, File!"], "example.txt", { type: "text/plain", lastModified: Date.now() });
console.log(file); 
// File { name: "example.txt", size: 12, type: "text/plain", lastModified: 1695644303000 }

File 对象继承了 Blob 对象的方法,因此可以使用一些 Blob 对象的方法来处理文件数据。
1、slice(): 从文件中获取一个子部分数据,返回一个新的 Blob 对象。

const blob = file.slice(0, 1024); // 获取文件的前 1024 个字节

const file = new File(["Hello World!"], "example.txt", { type: "text/plain" });
const blob = file.slice(0, 5); // 获取文件的前 5 个字节

blob.text().then((text) => {
  console.log(text); // 输出: "Hello"
});

2、text(): 读取文件内容,并将其作为文本返回(这是 Blob 的方法,但可以用于 File 对象)

const file = new File(["Sample content for file"], "example.txt", { type: "text/plain" });

file.text().then((text) => {
  console.log(text); // 输出: "Sample content for file"
});

3、arrayBuffer(): 将文件内容读取为 ArrayBuffer(用于处理二进制数据)。

const file = new File([new Uint8Array([65, 66, 67])], "example.bin");
file.arrayBuffer().then((buffer) => {
  const view = new Uint8Array(buffer);
  console.log(view); // 输出: Uint8Array(3) [65, 66, 67]
});

4、stream(): 返回一个 ReadableStream 对象,可以通过流式读取文件内容。

const stream = file.stream();

const file = new File(["Chunk 1\nChunk 2\nChunk 3"], "example.txt");

const reader = file.stream().getReader();
reader.read().then(function process({ done, value }) {
  if (done) {
    console.log("Stream complete");
    return;
  }
  console.log(new TextDecoder().decode(value)); // 输出文件的部分内容
  return reader.read().then(process);
});

总结

Blob 是一个通用的二进制数据容器,适合处理动态内容、文件片段等,但不具有文件的元数据(如文件名、最后修改时间等)。
File 是一个包含文件元信息的 Blob,主要用于用户上传文件的场景(File 对象看作是带有文件信息的 Blob)
在这里插入图片描述

二者在文件上传和二进制数据处理的场景中被广泛使用。Blob 更加通用,而 File 更专注于与文件系统的交互。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值