Blob File

news/2025/2/22 20:08:54/

文章目录

    • 学习链接
    • Blob
      • 创建
        • 演示
      • 分片
        • 演示
    • File
      • input
      • 手动拖拽
      • fetch 从后端获取流
        • 前端代码
        • 后端代码
      • window.showOpenFilePicker
    • Filereader
      • 示例1
      • 示例2
    • ArrayBuffer
      • 创建buffer
      • TypedArray读写buffer
      • DataView读写buffer
      • 与Blob对比
    • Blob Url & DataUrl
      • 示例1
      • 示例2

学习链接

Blog & File B站视频
今天一次性给你讲清楚:File、Blob、FileReader、ArrayBuffer、Base64
web前端文件上传可选择的4种方式
URL.createObjectURL和URL.revokeObjectURL

Blob

在这里插入图片描述

Blob 全称为 binary large object ,即二进制大对象。blob对象本质上是js中的一个对象,里面可以储存大量的二进制编码格式的数据。Blob 对象一个不可修改,从Blob中读取内容的唯一方法是使用 FileReader

创建

Blob() 构造函数返回一个新的 Blob 对象。blob 的内容由参数数组中给出的值的串联组成。

var aBlob = new Blob( array, options );

  • 其有两个参数:

    • array:是一个由ArrayBuffer, ArrayBufferView, Blob, DOMString 等对象构成的 Array ,或者其他类似对象的混合体,它将会被放进 Blob。DOMStrings 会被编码为 UTF-8。

    • options 是一个可选的BlobPropertyBag字典,它可能会指定如下两个属性:

      • type,默认值为 “”,它代表了将会被放入到 blob 中的数组内容的 MIME 类型。
      • endings,默认值为"transparent",用于指定包含行结束符\n的字符串如何被写入。它是以下两个值中的一个:“native”,代表行结束符会被更改为适合宿主操作系统文件系统的换行符,或者 “transparent”,代表会保持 blob 中保存的结束符不变 非标准

      在这里插入图片描述

演示

在这里插入图片描述
这个 blob 对象上有两个属性:

  • size:Blob对象中所包含数据的大小(字节);
  • type:字符串,认为该Blob对象所包含的 MIME 类型。如果类型未知,则为空字符串。

分片

Blob 对象内置了 slice() 方法用来将 blob 对象分片(注意:Blob对象是不可直接修改的,所以分片返回的是一个新的Blob对象

  • 其有三个参数:

    • start:设置切片的起点,即切片开始位置。默认值为 0,这意味着切片应该从第一个字节开始;

    • end:设置切片的结束点,会对该位置之前的数据进行切片。默认值为blob.size;

    • contentType:设置新 blob 的 MIME 类型。如果省略 type,则默认为 blob 的原始值。

演示

在这里插入图片描述

File

File 接口基于 Blob,继承了 blob 的功能并将其扩展以支持用户系统上的文件。File 对象是特殊类型的 Blob,比Blob要多一些文件相关的属性。

File() 构造器创建新的 File 对象实例:var myFile = new File(bits, name[, options]);

  • bits:一个包含ArrayBuffer,ArrayBufferView,Blob,或者 DOMString 对象的 Array — 或者任何这些对象的组合(所以可以这样创建File,new File([blob],‘test.zip’))。
  • name:表示文件名称,或者文件路径。
  • options: 可选,选项对象,包含文件的可选属性。可用的选项如下:
    • type: DOMString,表示将要放到文件中的内容的 MIME 类型。默认值为 “” 。
    • lastModified: 数值,表示文件最后修改时间的 Unix 时间戳(毫秒)。默认值为 Date.now()。

在 JavaScript 中,主要有两种方法来获取 File 对象:

  • <input> 元素上选择文件后返回的 FileList 对象;

  • 文件拖放操作生成的 DataTransfer 对象;

  • window.showOpenFilePicker

  • fetch 从后端获取

input

  • 但是,注意一下,每次change的时候,需要把这个input的value置为空,接着,仍然选择同一个文件时,也会触发这个change事件
  • 可以添加hidden属性,让这个input标签隐藏掉。或者,写css样式让它隐藏。然后,手动用js调用这个input的click事件。
    在这里插入图片描述

手动拖拽

在这里插入图片描述
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>.box {width: 300px;height: 300px;border: 1px solid red;}</style><script>window.onload = () => {let box = document.querySelector('.box')box.ondragover = (e) => {e.preventDefault();}box.ondrop = (e) => {e.preventDefault();let files = e.dataTransfer.filesconsole.log(files);}}</script>
</head>
<body><div class="box"></div>
</body>
</html>

fetch 从后端获取流

从这里,我们可以看到都可以从后端拿到Blob对象了,那就可以操作这个Blob了,前端就可以创建个a标签,添加上download属性,然后用js模拟点击这个a标签,然后把这个a标签移除掉。

在这里插入图片描述

前端代码

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>.box {width: 300px;height: 300px;border: 1px solid red;}</style><script>window.onload = () => {let btn = document.querySelector('#btn')btn.onclick = () => {fetch('http://127.0.0.1:8083/file/downloadFile?filename=avatar3.png').then(response => {console.log(response);return response.blob()// 注意,只能读取一次}).then(result=>{console.log(result);})}btn2.onclick = () => {fetch('http://127.0.0.1:8083/test.json').then(response => {console.log(response);return response.json() // 注意,只能读取一次}).then(result=>{console.log(result);})}}</script>
</head><body><button id="btn">获取avatar3.png</button><button id="btn2">获取test.json</button>
</body></html>

后端代码

@GetMapping("downloadFile")
public void downloadFile(@RequestParam("filename") String filename) throws Exception {// 告知浏览器这是一个字节流,浏览器处理字节流的默认方式就是下载// 意思是未知的应用程序文件,浏览器一般不会自动执行或询问执行。浏览器会像对待,// 设置了HTTP头Content-Disposition值为attachment的文件一样来对待这类文件,即浏览器会触发下载行为response.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE);// ,该响应头指示回复的内容该以何种形式展示,是以内联的形式(即网页或者网页的一部分),还是以附件的形式下载并保存到本地。response.setHeader(HttpHeaders.CONTENT_DISPOSITION,"attachment;fileName="+ URLEncoder.encode(filename, "UTF-8"));File file = new File("d:/Projects/practice/test-springboot/src/main/resources/file/" + filename);ServletOutputStream ros = response.getOutputStream();FileInputStream fis = new FileInputStream(file);byte[] bytes = new byte[2 * 1024];int len = 0;while ((len = fis.read(bytes)) != -1) {ros.write(bytes, 0, len);}ros.flush();ros.close();}@GetMapping("test.json")
public Object test2() {HashMap<String, Object> data = new HashMap<>();data.put("halo", "world");return data;
}

window.showOpenFilePicker

在这里插入图片描述

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script>window.onload = () => {document.getElementById('openImageFile').addEventListener('click', async () => {const handle = await showOpenFilePicker({multiple: true,types: [{description: '图片',accept: { 'image/png': ['.jpg', '.png'] }}]})if (handle && handle.length) {const handleFile = handle[0]const file = await handleFile.getFile()console.log(file);}}, false)}</script>
</head><body><button id="openImageFile">打开图片</button>
</body></html>

Filereader

通过上面我都知道了blob是不可修改也是无法读取里面的内容的。无法读取里面的内容肯定是不可行的。所以Filereader就提供了读取blob里面内容的方法

FileReader对象提供了以下方法来加载文件:

  • readAsArrayBuffer()∶读取指定Blob中的内容,完成之后,result属性中保存的将是被读取文件的ArrayBuffer数据对象;
  • readAsBinaryString()∶读取指定Blob中的内容,完成之后,result属性中将包含所读取文件的原始二进制数据;
  • readAsDataURL()︰读取指定Blob 中的内容,完成之后,result属性中将包含一个data: URL格式的 Base64字符串以表示所读取文件的内容。
  • readAsText()︰读取指定Blob 中的内容,完成之后,result属性中将包含一个字符串以表示所读取的文件内容。

在这里插入图片描述

示例1

将文件读取为base64 的字符串

在这里插入图片描述

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script>window.onload = () => {let iptFile = document.querySelector('#iptFile')iptFile.onchange = (e) => {console.log(e.target.files);let file = iptFile.files[0]let fileReader = new FileReader()fileReader.readAsDataURL(file)fileReader.onload = function(e) {console.log(e.target.result);}}}</script>
</head><body><input type="file" id="iptFile" name="file"/>
</body></html>

示例2

将存入的字符串的blob对象,读出来里面的内容
在这里插入图片描述

ArrayBuffer

我们可以把它理解为特殊的数组,特殊在哪里呢?

  • ArrayBuffer 本身就是一个黑盒,不能直接读写所存储的数据,需要借助以下视图对象来读写
  • TypedArray只是一个概念,实际使用的是那9个对象
    在这里插入图片描述
    在这里插入图片描述

创建buffer

new ArrayBuffer(bytelength)

  • 参数:它接受一个参数,即 bytelength,表示要创建数组缓冲区的大小(以字节为单位。)
    在这里插入图片描述

TypedArray读写buffer

在这里插入图片描述

DataView读写buffer

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

与Blob对比

  1. ArrayBuffer 与 Blob 有啥区别呢?根据 ArrayBuffer 和 Blob 的特性,Blob 作为一个整体文件,适合用于传输;当需要对二进制数据进行操作时(比如要修改某一段数据时),就可以使用 ArrayBuffer。

  2. 通过ArrayBuffer创建Blob,然后通过FileReader读取里面的内容

    在这里插入图片描述

Blob Url & DataUrl

  • 可以使用 File 或 Blob 生成对应的 Url(除了使用现成的file对象,我们也可以用上面的方法,自己创建File对象,然后传进去。)

    • URL.createObjectURL(blob) ; (blob url)

      • URL.revokeObjectURL:URL.revokeObjectURL()方法会释放一个通过URL.createObjectURL()创建的对象URL. 当你要已经用过了这个对象URL,然后要让浏览器知道这个URL已经不再需要指向对应的文件的时候,就需要调用这个方法.(可参考:URL.createObjectURL和URL.revokeObjectURL)
    • FileReader.readAsDataURL(file); (data url)

  • 生成的Url在一些a标签、img标签、iframe标签中可以使用。

    • 这样就可以实现比如,上传图片前,先预览图片的效果了

示例1

在这里插入图片描述

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script>window.onload = () => {let iptFile = document.querySelector('#iptFile')let a = document.querySelector('#a')let img = document.querySelector('#img')iptFile.onchange = (e) => {console.log(e.target.files);let file = iptFile.files[0]let blobUrl = URL.createObjectURL(file) ; console.log(blobUrl);a.href = blobUrlimg.src = blobUrl}}</script>
</head><body><input type="file" id="iptFile" name="file"/><a href="#" id="a" download>link</a>  <!-- 设置target='_blank'可以打开一个新页面;  加上download属性后,点击a标签可以下载,不加download的话,如果浏览器支持查看该文件,将会预览这个文件,如果不支持查看,将会下载这个文件;可以使用js模拟点击a标签,来触发下载 --><img src="" id="img" alt="err" style="width:50px;height:50px;">
</body></html>

示例2

与上面的效果一致,只不过换成了FileReader
在这里插入图片描述

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script>window.onload = () => {let iptFile = document.querySelector('#iptFile')let a = document.querySelector('#a')let img = document.querySelector('#img')iptFile.onchange = (e) => {console.log(e.target.files);let file = iptFile.files[0]let fileReader = new FileReader()fileReader.onload = (e) => {let dataUrl = fileReader.resulta.href = dataUrlimg.src = dataUrl}fileReader.readAsDataURL(file)}}</script>
</head><body><input type="file" id="iptFile" name="file"/><a href="#" id="a" download>link</a>  <!-- 设置target='_blank'可以打开一个新页面;  加上download属性后,点击a标签可以下载 --><img src="" id="img" alt="err" style="width:50px;height:50px;">
</body></html>

http://www.ppmy.cn/news/57926.html

相关文章

Linux安装Mysql操作步骤详解

目录 1. 检测当前系统中是否安装了MySql数据库 2. 使用FinalShell自带的上传工具将jdk的二进制发布包上传到Linux 3. 解压并解包到/usr/local/mysql&#xff08;便于区分&#xff09; 第一步&#xff1a;将包先移动到该目录下 第二步&#xff1a;解压解包 第三步&#xff1a…

瑞吉外卖管理端具体代码

目录 以下是后台的部分代码&#xff1a; EmployeeController CategoryController DishController SetmealController OrderController 具体的代码可到&#xff1a;reggie_take_out: 瑞吉外卖——功能实现 - Gitee.com 全部页面展示: 以下是后台的部分代码&#xf…

ChatGPT数据分析助手

ChatGPT数据分析助手 简介&#xff1a; ChatGPT数据分析助手是一款专业的数据库及表格数据分析及应用工具&#xff0c;采用先进的对话式交互方式&#xff0c;让您轻松应对各种业务场景。它能帮助您轻松解决数据分析问题&#xff0c;减轻数据分析学习压力&#xff0c;让您专注于…

HashMap基本知识详解

HashMap 是什么&#xff1f; HashMap 是一种用于存储键值对的集合&#xff0c;可以用来快速访问、插入和删除数据。在 HashMap 中&#xff0c;键和值都可以是任意对象。 HashMap 内部数据结构是什么&#xff1f; HashMap 是基于数组和链表&#xff08;或红黑树&#xff09;实现…

【五一创作】Python 一文了解 OS 操作系统交互库简单使用方法

作者主页&#xff1a;爱笑的男孩。的博客_CSDN博客-深度学习,活动,YOLO领域博主爱笑的男孩。擅长深度学习,活动,YOLO,等方面的知识,爱笑的男孩。关注算法,python,计算机视觉,图像处理,深度学习,pytorch,神经网络,opencv领域.https://blog.csdn.net/Code_and516?typecollect个人…

正则表达式学习笔记

re.match()的使用 尝试从字符串的起始位置匹配一个模式&#xff0c;如果不是起始位置匹配成功的话&#xff0c;match&#xff08;&#xff09;就返回None 1.最常规的匹配 import re contect Hello 123 456789 World_this is a Regex Demores re.match(^Hello\s\d\d\d\s\d{6…

营收、利润增速第一!海尔智家为何领跑?

“企业只有保持领先的能力&#xff0c;才有可能取得经济成果。” 管理学大师德鲁克曾如此强调。所谓“领先”&#xff0c;就是独一无二的、有价值的东西。利润&#xff0c;是企业在某个领域取得领先优势后&#xff0c;必然获得的回报。 这种“领先优势”&#xff0c;在各行业…

c++ 虚函数

虚函数的理解 1、c virtual 函数作用&#xff1a;如果重写的函数中有重名的函数&#xff0c;那么则调用重写的函数 2、 如果不是虚函数&#xff0c;则调用继承的函数 3、“重写”的要求是函数的特征标&#xff08;包括参数的数目、类型和顺序&#xff09;以及返回值都必须与基类…