JavaScript 中,File、Blob、Base64 和 ArrayBuffer 不同的用途和转换方法。

JavaScript 中,File、Blob、Base64 和 ArrayBuffer 不同的用途和转换方法。

Blob:

  • 概念:代表不可变的原始数据二进制块,可以是图片、视频等数据。
  • 用途:用于处理二进制数据、文件上传和下载、创建文件对象。
// 创建一个 Blob 对象
const blob = new Blob(["Hello, world!"], { type: "text/plain" });
// 创建对象 URL
const url = URL.createObjectURL(blob);

//从 Blob 转换为 File:
const file = new File([blob], "hello.txt", { type: "text/plain", lastModified: new Date() });

//从 Blob 转换为 Base64:
const reader = new FileReader();
reader.onloadend = () => {
    const base64 = reader.result.split(",")[1]; // Remove the data URL prefix
    console.log(base64);
};
reader.readAsDataURL(blob);

//从 Blob 转换为 ArrayBuffer:
const reader = new FileReader();
reader.onload = (e) => {
    const arrayBuffer = e.target.result;
    console.log(arrayBuffer);
};
reader.readAsArrayBuffer(blob);

File:

  • 概念:File 是 Blob 的子类,代表用户上传的文件对象,包含文件名、文件类型等信息。
  • 用途:用于表示文件对象,通常来自用户输入的文件(如通过 )。
//从 File 转换为 Blob:
const file = document.querySelector('input[type="file"]').files[0];
const blob = new Blob([file], { type: file.type });

//从 File 转换为 base64:
const reader = new FileReader();
reader.onload = function (event) {
    // 获取 Base64 编码的结果
    const base64String = event.target.result.split(",")[1];
    console.log(base64String);
};
reader.readAsDataURL(file);

//从 File 转换为 ArrayBuffer:
const reader = new FileReader();
reader.onload = (e) => {
    const arrayBuffer = e.target.result;
    console.log(arrayBuffer);
};
reader.readAsArrayBuffer(file);

Base64:

  • 概念:一种编码方式,将二进制数据编码为 ASCII 字符串。
  • 用途:用于在 URL 或 HTML 中嵌入小的图像、文件,方便传输,但数据会变得更大。
// 将文本编码为 Base64
const base64 = btoa("Hello, world!");
// 解码 Base64
const decoded = atob(base64);

//从 Base64 转换为 Blob:
const base64 = "data:text/plain;base64,SGVsbG8sIHdvcmxkIQ==";
const response = await fetch(base64);
const blob = await response.blob();

//从 Base64 转换为 ArrayBuffer:
const base64 = "SGVsbG8sIHdvcmxkIQ==";
const binaryString = atob(base64);
const len = binaryString.length;
const bytes = new Uint8Array(len);
for (let i = 0; i < len; i++) {
    bytes[i] = binaryString.charCodeAt(i);
}
const arrayBuffer = bytes.buffer;
console.log(arrayBuffer);

Buffer:

  • 概念:在 Node.js 环境中使用的用于处理原始二进制数据的对象。提供了更多用于操作和管理二进制数据的方法,特别适合处理文件系统和网络流数据。
  • 用途:用于处理二进制数据的类,特别适合处理文件、网络流、加密操作等。常用于文件系统操作、网络请求和响应处理等 Node.js 环境中。
  • 特点:
    • 高效:Buffer 在 Node.js 中用于处理二进制数据,提供了高效的内存管理。自身具有丰富的方法来直接操作数据。
    • 方法丰富:提供了很多内置的方法用于操作二进制数据,如 write, slice, toString, fill 等。
    • Node.js 专用:是 Node.js 的核心部分,不直接在浏览器中使用。
// 创建一个 Buffer 对象,包含字符串数据
const buffer = Buffer.from("Hello, world!", "utf-8");

// 输出 Buffer 内容
console.log(buffer); // 输出: <Buffer 48 65 6c 6c 6f 2c 20 77 6f 72 6c 64 21>

// 将 Buffer 转换为字符串
console.log(buffer.toString()); // 输出: Hello, world!

ArrayBuffer:

  • 概念:是一个用于表示通用、固定长度的原始二进制数据缓冲区。提供原始的二进制数据缓冲区,通常用于处理和传输数据。
  • 用途:用于 Web 开发中的二进制数据处理,如从 Blob 读取数据、处理 WebSockets 的二进制数据等。
  • 特点:ArrayBuffer 本身是不可变的。它是二进制数据的原始缓冲区,不能直接进行读写操作。
  • 视图: 可以通过不同的视图(TypedArray)(如 Uint8Array, Int16Array, Float32Array 等)来读写 ArrayBuffer 中的数据。
  • Web API:是 Web 标准的一部分,广泛用于 Web 应用程序中、用于浏览器环境。
// 创建一个 16 字节的 ArrayBuffer
const buffer = new ArrayBuffer(16);

// 创建一个视图来读取和写入数据
const view = new Uint8Array(buffer);

// 设置数据
view[0] = 42;

// 读取数据
console.log(view[0]); // 输出: 42

//从 ArrayBuffer 转换为 Blob:
const blob = new Blob([arrayBuffer], { type: "application/octet-stream" });

//从 ArrayBuffer 转换为 Base64:
const base64 = btoa(String.fromCharCode(...new Uint8Array(arrayBuffer)));
console.log(base64);

常用转换函数

base64ToFile

function base64ToFile(base64String, fileName) {
    // 从 Base64 字符串中提取 MIME 类型和编码数据
    const [header, base64Data] = base64String.split(",");
    const mime = header.match(/:(.*?);/)[1];

    // 解码 Base64 数据
    const binaryString = atob(base64Data);
    const arrayBuffer = new ArrayBuffer(binaryString.length);
    const uint8Array = new Uint8Array(arrayBuffer);

    // 将解码的数据填充到 Uint8Array 中
    for (let i = 0; i < binaryString.length; i++) {
        uint8Array[i] = binaryString.charCodeAt(i);
    }

    // 创建 Blob 对象
    const blob = new Blob([uint8Array], { type: mime });

    // 创建 File 对象
    return new File([blob], fileName, { type: mime });
}

dataURLtoBlob

/**
 * base64编码的dataURL转化为Blob不可变二进制数据
 * @param {String} dataURL base64编码的dataURL字符串,格式比如 data:image/png;base64,经过base64编码的字符串
 * @result {Object} 返回值为Blob对象
 */
export function dataURLtoBlob(dataURL) {
    //获取MIME类型
    let mime = dataURL.split(",")[0].split(":")[1].split(";")[0];
    //对经过base64编码的数据进行解码
    let byteString = window.atob(dataURL.split(",")[1]);
    // 创建内存
    let arrayBuffer = new ArrayBuffer(byteString.length);
    // 生成内存的视图,通过TypeArray对象操作二进制
    let typeArray = new Uint8Array(arrayBuffer);
    // 遍历二进制数据通过typeArray对象将数据存储到arrayBuffer对象中
    for (let i = 0; i < byteString.length; i++) {
        typeArray[i] = byteString.charCodeAt(i);
    }
    // 生成blob数据
    return new Blob([typeArray], { type: mime });
}

binaryToDataURL

/**
 * 将binary(二进制)数据转化为base64编码的DataURL字符串
 * @param {Object} data Blob类型或file类型的数据
 * @param {Function} fn 回调函数
 */
export function binaryToDataURL(data, fn) {
    if (window.FileReader) {
        const file = new FileReader();
        //如果data为空返回null
        if (data == undefined) return fn(null);
        file.onload = function (e) {
            fn(e.target.result);
        };
        file.readAsDataURL(data);
    }
}

导出 csv

/**
 * 前端导出csv格式表格(没有表格线),但是不支持合并表格和图片导出,并且解决了csv文件过大下载失败的问题
 * @param {String} str 标题字符串,格式: '标题1,标题2,标题3...'
 * @param {array} dataList 数据数组, 格式: [{},{},{}...]
 * @param {String} fileName 保存文件名
 */
export function exportCSV(str, dataList, fileName) {
    fileName = fileName || new Date().getTime();
    //标题
    str = str + "\n";
    //增加\t为了不让表格显示科学计数法或者其他格式
    for (let i = 0; i < dataList.length; i++) {
        for (let item in dataList[i]) {
            str += `${dataList[i][item] + "\t"},`;
        }
        str += "\n";
    }
    //在字符串前面添加\ufeff解决构造Blob中文乱码问题
    str = "\ufeff" + str;
    //构造Blob数据(text/plain纯文本格式)
    let blob = new Blob([str], { type: "text/plain;charset=utf-8" });
    //创建url和下载标签
    let url = window.URL.createObjectURL(blob);
    let link = document.createElement("a");
    link.href = url;
    link.download = fileName + ".csv";
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    //释放url对象
    window.URL.revokeObjectURL(url);
}

导出文件

/**
 * 下载二进制数据(ajax请求需设置responseType: "blob"或"arraybuffer")
 * @param {Blob} data 二进制数据 必填
 * @param {string} fileName 文件名称 必填
 * @param {string} type 文件后缀 必填
 */
export function saveAsBinary(data, fileName, type) {
    if (!fileName || !type) {
        console.error("please set file name and file type");
    }

    // 转换成blob数据
    let blob = null;
    if (isBlob(data)) {
        blob = data;
    } else if (isArrayBuffer(data)) {
        blob = new Blob([data], { type: FileAndMIME[type] });
    } else {
        return;
    }

    // ie浏览器兼容
    if (window.navigator.msSaveOrOpenBlob) {
        navigator.msSaveBlob(blob, `${fileName}.${type}`);
    } else if (window.URL) {
        //创建a标签
        const link = document.createElement("a");
        //获取body元素
        const body = document.querySelector("body");
        //创建url链接
        link.href = window.URL.createObjectURL(blob);
        //重命名
        link.download = `${fileName}.${type}`;
        //火狐需要隐藏标签
        link.style.display = "none";
        //插入到body中
        body.appendChild(link);
        //触发下载
        link.click();
        //移除a标签
        body.removeChild(link);
        //释放url对象
        window.URL.revokeObjectURL(link.href);
    }
}

常用 office 文件对应的 MIME TYPE 和后缀

export const FileAndMIME = {
    ".doc": "application/msword",
    ".dot": "application/msword",
    ".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
    ".dotx": "application/vnd.openxmlformats-officedocument.wordprocessingml.template",
    ".docm": "application/vnd.ms-word.document.macroEnabled.12",
    ".dotm": "application/vnd.ms-word.template.macroEnabled.12",
    ".xls": "application/vnd.ms-excel",
    ".xlt": "application/vnd.ms-excel",
    ".xla": "application/vnd.ms-excel",
    ".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
    ".xltx": "application/vnd.openxmlformats-officedocument.spreadsheetml.template",
    ".xlsm": "application/vnd.ms-excel.sheet.macroEnabled.12",
    ".xltm": "application/vnd.ms-excel.template.macroEnabled.12",
    ".xlam": "application/vnd.ms-excel.addin.macroEnabled.12",
    ".xlsb": "application/vnd.ms-excel.sheet.binary.macroEnabled.12",
    ".ppt": "application/vnd.ms-powerpoint",
    ".pot": "application/vnd.ms-powerpoint",
    ".pps": "application/vnd.ms-powerpoint",
    ".ppa": "application/vnd.ms-powerpoint",
    ".pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
    ".potx": "application/vnd.openxmlformats-officedocument.presentationml.template",
    ".ppsx": "application/vnd.openxmlformats-officedocument.presentationml.slideshow",
    ".ppam": "application/vnd.ms-powerpoint.addin.macroEnabled.12",
    ".pptm": "application/vnd.ms-powerpoint.presentation.macroEnabled.12",
    ".potm": "application/vnd.ms-powerpoint.presentation.macroEnabled.12",
    ".ppsm": "application/vnd.ms-powerpoint.slideshow.macroEnabled.12",
};

总结

  • File 和 Blob 用于处理文件和二进制数据。
  • Base64 用于编码和嵌入二进制数据。适合小量数据嵌入。
  • ArrayBuffer 用于处理原始二进制数据缓冲区。
  • Buffer 主要用于 Node.js 环境处理原始数据。
  • 16
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值