分类 技术杂谈 下的文章 - Lino笔记
首页
笔记
关于
友链
壁纸
留言板
搜 索
1
Joe主题重制版 - 本站同款
117 阅读
2
小米手机刷面具教程(纯小白篇)
33 阅读
3
MAC PD19 破解
20 阅读
4
CNS服务器搭建(配合百度直连)
18 阅读
5
label标签中的for属性
15 阅读
技术杂谈
生活随笔
日常分享
杂七杂八
登录
搜 索
标签搜索
JS
博客部署
心理学
mysql
hexo
异步编程
Promise函数
ShadowSocks
代理
境外服务器
typecho主题
网易云
价值观
Typora
破解
笔记
centOS
redis
Joe主题
代码整洁
Lino
累计撰写
27
篇文章
累计收到
8
条评论
首页
栏目
技术杂谈
生活随笔
日常分享
杂七杂八
页面
笔记
关于
友链
壁纸
留言板
用户登录
登录
找到
16
篇与
技术杂谈
相关的结果
2023-11-10
利用Python连接mysql数据库及简单增删改查操作示例代码
安装mysql模块我们先确认是否已经安装了mysql模块。通过以下步骤可以快速检查:打开终端或命令提示符。输入命令pip freeze,查看当前已安装的Python模块列表。在输出结果中查找是否包含mysql-connector-python或类似的条目。如果没有找到mysql-connector-python,则说明尚未安装mysql模块,我们需要进行安装。在确认未安装mysql模块后,我们需要使用pip命令来安装mysql-connector-python模块。执行以下命令: pip install mysql-connector-python 安装完成后,我们需要在Python代码中导入mysql模块,以便在代码中正确使用该模块。在需要使用mysql模块的代码文件的开头添加以下代码: import mysql.connector创建数据库和表在MySQL中创建一个名为test的数据库,并在其中创建一个名为user的表: CREATE DATABASE test; USE test; CREATE TABLE user ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255), age INT ); 连接数据库在Python中连接MySQL数据库需要使用mysql-connector-python库中的connect()方法,需要传入host、user、password和database等参数。如果连接成功,我们可以得到一个连接对象。 import mysql.connector mydb = mysql.connector.connect( host="localhost", user="root", password="123456", database="test" ) print(mydb) 插入数据接下来我们可以通过连接对象的cursor()方法得到一个游标对象,使用execute()方法执行SQL语句。下面是插入数据的示例代码: import mysql.connector mydb = mysql.connector.connect( host="localhost", user="root", password="123456", database="test" ) mycursor = mydb.cursor() sql = "INSERT INTO user (name, age) VALUES (%s, %s)" val = ("Tom", 18) mycursor.execute(sql, val) mydb.commit() print(mycursor.rowcount, "record inserted.") 查询数据我们可以使用SELECT语句查询数据,使用fetchall()方法获取全部数据或使用fetchone()方法获取一条数据。下面是查询数据的示例代码: import mysql.connector mydb = mysql.connector.connect( host="localhost", user="root", password="123456", database="test" ) mycursor = mydb.cursor() mycursor.execute("SELECT * FROM user") myresult = mycursor.fetchall() for x in myresult: print(x) 更新数据我们可以使用UPDATE语句更新数据,使用execute()方法执行SQL语句。下面是更新数据的示例代码: import mysql.connector mydb = mysql.connector.connect( host="localhost", user="root", password="123456", database="test" ) mycursor = mydb.cursor() sql = "UPDATE user SET age = %s WHERE name = %s" val = (20, "Tom") mycursor.execute(sql, val) mydb.commit() print(mycursor.rowcount, "record(s) affected") 删除数据我们可以使用DELETE语句删除数据,使用execute()方法执行SQL语句。下面是删除数据的示例代码: import mysql.connector mydb = mysql.connector.connect( host="localhost", user="root", password="123456", database="test" ) mycursor = mydb.cursor() sql = "DELETE FROM user WHERE name = %s" val = ("Tom",) mycursor.execute(sql, val) mydb.commit() print(mycursor.rowcount, "record(s) deleted")
2023年11月10日
11 阅读
0 评论
1 点赞
2023-11-06
win系统下部署mysql服务(免安装版)及常见小问题解决方法
下载MySQLMySQL下载官网下载对应版本MySQL配置环境变量在系统变量中创建MYSQL_HOME变量:MySQL文件路径例如:D:\mysql\mysql-5.6.15-winx64在系统变量和用户变量中加PATH:%MYSQL_HOME%\bin 文件配置本次安装以mysql-5.6.15-winx64为例,将安装包解压之后,进入解压后的目录找到my.ini配置文件,没有的话就自行创建my.ini配置文件,这个文件是mysql的主配置文件,修改如下内容指定数据库存放位置basedir = D:\mysql\mysql-5.6.15-winx64 #MySQL文件路径 datadir = D:\mysql\mysql-5.6.15-winx64\data #MySQL数据存放路径,如果没有data文件夹自行创建 port=3306 max_connections=200 character-set-server=utf8 default-storage-engine=INNODB # For advice on how to change settings please see # http://dev.mysql.com/doc/refman/5.6/en/server-configuration-defaults.html # *** DO NOT EDIT THIS FILE. It's a template which will be copied to the # *** default location during install, and will be replaced if you # *** upgrade to a newer version of MySQL. [mysqld] # Remove leading # and set to the amount of RAM for the most important data # cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%. # innodb_buffer_pool_size = 128M # Remove leading # to turn on a very important data integrity option: logging # changes to the binary log between backups. # log_bin # These are commonly set, remove the # and set as required. # basedir = ..... # datadir = ..... # port = ..... # server_id = ..... basedir = D:\mysql\mysql-5.6.15-winx64 datadir = D:\mysql\mysql-5.6.15-winx64\data port=3306 max_connections=200 character-set-server=utf8 default-storage-engine=INNODB # Remove leading # to set options mainly useful for reporting servers. # The server defaults are faster for transactions and fast SELECTs. # Adjust sizes as needed, experiment to find the optimal values. # join_buffer_size = 128M # sort_buffer_size = 2M # read_rnd_buffer_size = 2M 安装服务在通过管理员身份打开cmd,注意一定是要用管理员身份打开输入 mysqld install MySQL --default-file="D:\mysql\mysql-5.6.15-winx64\my.ini" 提示successfull表示安装成功,启动MySQL服务net start mysql,停止可以使用net stop mysql,当然也可以在服务里面进行操作初始化数据库cmd中输入mysqld --initialize 如果报错的话: 配置文件增加[mysqld] explicit_defaults_for_timestamp=true这时会在data文件夹下找到一个xxx.err的文件此时打开该文件root@localhost后就是随机生成的初始密码[Note] A temporary password is generated for root@localhost: VhaS8aL+#RrG启动服务net start mysql进入数据库,默认是没有密码回车就行mysql -u root -p重新设置密码(若提示Can't connect to MySQL server on 'localhost' (10061),说明MySQL服务没起,应先执行net start mysql,若无法启动服务,重启电脑就行了):重新设置密码set password = password('123456')再一次提示一定要配置好环境变量MySQL_HOME注意点:1.需要在bin目录下以管理员身份进行cmd2.mysqld --initialize --console初始会生成默认默认密码3.如果不想在每次不想bin目录才能执行mysql命令,可以配置环境变量,其实可以不用配置,一般不用cmd操作数据库。一些常见错误解决办法启动MySQL出现以下错误提示:MySQL 服务正在启动 MySQL 服务无法启动。服务没有报告任何错误。请键入 NET HELPMSG 3534 以获得更多的帮助。 一般有几个情况:MySQL安装文件夹的data文件夹不完整或者被移动了1.如果是Data文件夹里面的文件不完整,那么就先清空原来的Data文件夹,然后输入mysqld --initialize初始化Data,如果可能有报错,但是没反应可以到Data文件夹里的.err文件查看原因;或者可以输入mysqld --initialize --console在控制台就能看到报错信息。2、如果是data文件夹的位置发生了变化,就要根据文件夹的新目录修改my.ini文件中basedir=?和datadir=?这两个文件的存储位置了,另外,如果MySQL的文件夹也发生位置变化,比如加装了移动硬盘,重新分区;环境变量也需要跟着修改配置。以上两个情况都初始化一下mysqld --initialize会比较保险。安装服务的话输入 mysqld --install 服务名 如:mysqld --install MySQL56删除服务的话输入 sc delete 服务名 如:sc delete MySQL56总结可能会用到的命令:mysqld --initialized -insecure:初始化MySQL,并且默认密码为空;mysqld --initialized --console:初始化MySQL;mysqld --install:安装MySQL服务;mysqld -remove:删除MySQL服务;mysql -u 用户名 -p:登录MySQL;alter user 'root'@'localhost'identified by '密码';:修改管理员用户的密码;MySQL服务的可执行文件路径不正确右键我的电脑—>管理—>服务—>找到自己mysql的服务—>右键属性打开如果路径有 -default的需要删掉当前可执行文件的路径为:"D:\mysql\mysql-5.6.15-winx64\bin\mysqld" -defaultPath="D:\mysql\mysql-5.6.15-winx64\bin\mysqld" MySQL80"D:\mysql\mysql-5.6.15-winx64\bin\mysqld" -defaultPath="D:\mysql\mysql-5.6.15-winx64\bin\mysqld" MySQL56修改步骤:win+R键输入regdit按照路径找到自己的mysql服务注册表例如:计算机\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MySQL56修改ImagePath为"D:\mysql\mysql-5.6.15-winx64\bin\mysqld" MySQL56 然后服务启动MySQL56 或者 cmd里面输入 net start MySQL56 正常运行。问题解决。忘记密码登录时跳过权限检查并修改密码找到MySQL配置文件my.ini打开文件在[mysqld]后添加kip-grant-tables然后重启MySQL服务在终端中输入net stop mysql net start mysq或者打开windows任务管理器重启部署的MySQL服务重启后登录mysql,输入mysql –uroot –p;直接回车(Enter)输入select host, user from user;会出现用户列表,例如下表+-----------+---------------+ | host | user | +-----------+---------------+ | localhost | root | | localhost | mysql.session | | localhost | mysql.sys | +-----------+---------------+选择要修改密码的用户使用以下命令修改set password for ‘用户名’@‘host’=password(‘要修改的密码’);例如这里我将root用户密码修改为123456,用以下命令即可:set password for ‘root’@‘localhost’=password(‘123456’);然后刷新flush privileges;重启mysql服务密码即可修改成功navicat连接mysql报错1130-Host ‘1xxx.xx.x.20‘ is not allowed to connect to this MySQL server的解决办法navicat连接mysql报错1130-Host '1xxx.xx.x.20' is not allowed to connect to this MySQL server的解决办法原因:没有权限解决办法:1、连接服务器: mysql -u root -p2、看当前所有数据库:show databases;3、进入mysql数据库:use mysql;4、查看mysql数据库中所有的表:show tables5、查看user表中的数据:select host, user from user;6、修改user表中的Host:update user set host='%' where user='要修改权限的用户名';7、最后刷新一下:flush privileges; %的意思:Host列指定了允许用户登录所使用的IP,比如user=root Host=192.168.1.1。这里的意思就是说root用户只能通过192.168.1.1的客户端去访问。而%是个通配符,如果Host=192.168.1.%,那么就表示只要是IP地址前缀为“192.168.1.”的客户端都可以连接。如果Host=%,表示所有IP都有连接权限。这也就是为什么在开启远程连接的时候,大部分人都直接把Host改成%的缘故,为了省事。
2023年11月06日
15 阅读
0 评论
1 点赞
2023-10-13
label标签中的for属性
使用介绍label中的for属性规定了label与哪个表单元素绑定。for属性的值和表单元素的id值一样,即可完成该label标签与该表单元素的绑定。<label for="test">label标签</label> <input type="text" id="test">如上所示,该label便签和input便签完成了绑定,当鼠标点击“label标签”时,input元素会被触发,用户即可完成输入。为什么要给label标签加上for属性呢?label标签加上for属性绑定了表单元素后,可以提高用户体验。当点击label标签内的文本后,就会触发绑定的表单元素。也就是说,当用户渲染该标签时,浏览器就会自动将焦点转到绑定的表单控件上。ps:表单控件input、select、textarea、button和h5的datalist、keygen、output。其中当label标签和select标签绑定后,点击label标签文本内容,不能触发select便签
2023年10月13日
15 阅读
0 评论
0 点赞
2023-09-22
小米手机刷面具教程(纯小白篇)
刷面具的前提已解BL锁,如果不懂可以看这篇小米解BL锁教程安装magisk软件并刷入magisk下载面具magisk官网 下载最新版magiskmanager软件安装到手机上下载当前版本官方未解密完整包下载好当前版本官方未解密完整包(注意是未解密)很多小伙伴不知道怎么获得未解密的官方包,我多说两句设置 ➜ 我的设备 ➜ MIUI版本 ➜ 左上角的3个点 ➜ 下载最新完整包下载到 1% 的时候然后停止下载然后去“下载管理”继续下载这样就不会被系统解密了下载好的包在Download\downloaded_rom 就可以找到了提取boot.img用 MT管理器 打开完整包把boot.img提取出来右侧记得选一个自己容易找到的解压位置修补boot.img打开已经安装好的Magisk Manager首先选择设置-更新通道改为测试版然后回到主页面选择安装-选择修补一个文件-找到并选择你刚提取的boot.img文件修补好后在你原来的下载目录下会生成一个 magisk_patched_xxx.img 的文件(文件名可能会有差异)刷入修补后的boot.img将生成的 magisk_patched_xxx.img 的文件将他它改名为magisk_patched将这个文件拷贝到电脑上下载Flash Boot 通刷包解压把改名的magisk_patched文件复制替换进来将手机重启至fast boot模式然后数据线连接电脑双击“打开CMD命令行”在CMD窗口内输入以下命令:非A/B 分区机型:fastboot flash boot magisk_path.imgA/B机型(如小米11)要刷两次:fastboot flash boot_a magisk_path.imgfastboot flash boot_b magisk_path.img等待窗口内出现两个OK字样就完成了拔掉数据线重启手机即可至此就完成小米手机刷面具ROOT操作了。
2023年09月22日
33 阅读
0 评论
0 点赞
2023-09-18
浅谈前端中的二进制数据类型
目前在一个项目中,WebSocket部分由于后端使用了gzip压缩,前端处理起来废了一点时间,从而发现自己在二进制数据类型这个知识点还存在一定的盲区,因此这里进行总结。本文主要简单介绍ArrayBuffer对象、TypedArray对象、DataView对象以及Blob原始数据类型,和它们之间的互相转换方法。部分代码参考这里而非本人原创,仅做个人学习使用。这些类型化对象,一般会在以下场景中使用:WebGL 中,浏览器和显卡之间需要使用二进制数据进行通信。在一些 Rest 接口或者 WebSocket 中,采用压缩过的数据进行通信,这个压缩和解压缩的过程可能需要借助二进制对象。在 Canvas 中,我们可能需要通过生成 Blob 的方式保存当前内容。在 Img 等资源文件中,URL 可以为 Blob 原始数据类型。在读取用户上传文件时,可能需要用到二进制数据类型进行中间转换。下文分两部分,前一部分概述各个二进制数据类型,后一部分将它们之间的互相转换。二进制数据类型概述ArrayBufferArrayBuffer对象代表储存二进制数据的一段内存,它不能直接读写,只能通过视图(TypedArray视图和DataView视图)来读写,视图的作用是以指定格式解读二进制数据。ArrayBuffer也是一个构造函数,可以分配一段可以存放数据的连续内存区域。var buf = new ArrayBuffer(32);上面代码生成了一段32字节的内存区域,每个字节的值默认都是0。可以看到,ArrayBuffer构造函数的参数是所需要的内存大小(单位字节)。为了读写这段内容,需要为它指定视图。DataView视图的创建,需要提供ArrayBuffer对象实例作为参数。var buf = new ArrayBuffer(32); var dataView = new DataView(buf); dataView.getUint8(0) // 0上面代码对一段32字节的内存,建立DataView视图,然后以不带符号的8位整数格式,读取第一个元素,结果得到0,因为原始内存的ArrayBuffer对象,默认所有位都是0。另外,我们可以将ArrayBuffer生成的结果,传入TypedArray中:var buffer = new ArrayBuffer(12); var x1 = new Int32Array(buffer); x1[0] = 1; var x2 = new Uint8Array(buffer); x2[0] = 2; x1[0] // 2ArrayBuffer实例的byteLength属性,返回所分配的内存区域的字节长度。var buffer = new ArrayBuffer(32); buffer.byteLength // 32如果要分配的内存区域很大,有可能分配失败(因为没有那么多的连续空余内存),所以有必要检查是否分配成功。if (buffer.byteLength === n) { // 成功 } else { // 失败 }ArrayBuffer实例有一个slice方法,允许将内存区域的一部分,拷贝生成一个新的ArrayBuffer对象。var buffer = new ArrayBuffer(8); var newBuffer = buffer.slice(0, 3);上面代码拷贝buffer对象的前3个字节(从0开始,到第3个字节前面结束),生成一个新的ArrayBuffer对象。slice方法其实包含两步,第一步是先分配一段新内存,第二步是将原来那个ArrayBuffer对象拷贝过去。slice方法接受两个参数,第一个参数表示拷贝开始的字节序号(含该字节),第二个参数表示拷贝截止的字节序号(不含该字节)。如果省略第二个参数,则默认到原ArrayBuffer对象的结尾。除了slice方法,ArrayBuffer对象不提供任何直接读写内存的方法,只允许在其上方建立视图,然后通过视图读写。ArrayBuffer有一个静态方法isView,返回一个布尔值,表示参数是否为ArrayBuffer的视图实例。这个方法大致相当于判断参数,是否为TypedArray实例或DataView实例。var buffer = new ArrayBuffer(8); ArrayBuffer.isView(buffer) // false var v = new Int32Array(buffer); ArrayBuffer.isView(v) // trueTypedArray目前,TypedArray对象一共提供9种类型的视图,每一种视图都是一种构造函数。Int8Array:8位有符号整数,长度1个字节。Uint8Array:8位无符号整数,长度1个字节。Uint8ClampedArray:8位无符号整数,长度1个字节,溢出处理不同。Int16Array:16位有符号整数,长度2个字节。Uint16Array:16位无符号整数,长度2个字节。Int32Array:32位有符号整数,长度4个字节。Uint32Array:32位无符号整数,长度4个字节。Float32Array:32位浮点数,长度4个字节。Float64Array:64位浮点数,长度8个字节。这9个构造函数生成的对象,统称为TypedArray对象。它们很像正常数组,都有length属性,都能用方括号运算符([])获取单个元素,所有数组的方法,在类型化数组上面都能使用。两者的差异主要在以下方面。TypedArray数组的所有成员,都是同一种类型和格式。TypedArray数组的成员是连续的,不会有空位。Typed化数组成员的默认值为0。比如,new Array(10)返回一个正常数组,里面没有任何成员,只是10个空位;new Uint8Array(10)返回一个类型化数组,里面10个成员都是0。TypedArray数组只是一层视图,本身不储存数据,它的数据都储存在底层的ArrayBuffer对象之中,要获取底层对象必须使用buffer属性。构造函数TypedArray数组提供9种构造函数,用来生成相应类型的数组实例。构造函数有多种用法。TypedArray(buffer, byteOffset=0, length?)同一个ArrayBuffer对象之上,可以根据不同的数据类型,建立多个视图。// 创建一个8字节的ArrayBuffer var b = new ArrayBuffer(8); // 创建一个指向b的Int32视图,开始于字节0,直到缓冲区的末尾 var v1 = new Int32Array(b); // 创建一个指向b的Uint8视图,开始于字节2,直到缓冲区的末尾 var v2 = new Uint8Array(b, 2); // 创建一个指向b的Int16视图,开始于字节2,长度为2 var v3 = new Int16Array(b, 2, 2);对于以上代码,v1、v2和v3是重叠的:v1[0]是一个32位整数,指向字节0~字节3;v2[0]是一个8位无符号整数,指向字节2;v3[0]是一个16位整数,指向字节2~字节3。只要任何一个视图对内存有所修改,就会在另外两个视图上反应出来。注意,byteOffset必须与所要建立的数据类型一致,否则会报错。var buffer = new ArrayBuffer(8); var i16 = new Int16Array(buffer, 1); // Uncaught RangeError: start offset of Int16Array should be a multiple of 2上面代码中,新生成一个8个字节的ArrayBuffer对象,然后在这个对象的第一个字节,建立带符号的16位整数视图,结果报错。因为,带符号的16位整数需要两个字节,所以byteOffset参数必须能够被2整除。如果想从任意字节开始解读ArrayBuffer对象,必须使用DataView视图,因为TypedArray视图只提供9种固定的解读格式。TypedArray(length)视图还可以不通过ArrayBuffer对象,直接分配内存而生成。var f64a = new Float64Array(8); f64a[0] = 10; f64a[1] = 20; f64a[2] = f64a[0] + f64a[1];TypedArray(typedArray)类型化数组的构造函数,可以接受另一个视图实例作为参数。var typedArray = new Int8Array(new Uint8Array(4));上面代码中,Int8Array构造函数接受一个Uint8Array实例作为参数。注意,此时生成的新数组,只是复制了参数数组的值,对应的底层内存是不一样的。新数组会开辟一段新的内存储存数据,不会在原数组的内存之上建立视图。var x = new Int8Array([1, 1]); var y = new Int8Array(x); x[0] // 1 y[0] // 1 x[0] = 2; y[0] // 1上面代码中,数组y是以数组x为模板而生成的,当x变动的时候,y并没有变动。如果想基于同一段内存,构造不同的视图,可以采用下面的写法。var x = new Int8Array([1, 1]); var y = new Int8Array(x.buffer); x[0] // 1 y[0] // 1 x[0] = 2; y[0] // 2TypedArray(arrayLikeObject)构造函数的参数也可以是一个普通数组,然后直接生成TypedArray实例。var typedArray = new Uint8Array([1, 2, 3, 4]);注意,这时TypedArray视图会重新开辟内存,不会在原数组的内存上建立视图。上面代码从一个普通的数组,生成一个8位无符号整数的TypedArray实例。TypedArray数组也可以转换回普通数组。var normalArray = Array.prototype.slice.call(typedArray);BYTES_PER_ELEMENT属性每一种视图的构造函数,都有一个BYTES_PER_ELEMENT属性,表示这种数据类型占据的字节数。Int8Array.BYTES_PER_ELEMENT // 1 Uint8Array.BYTES_PER_ELEMENT // 1 Int16Array.BYTES_PER_ELEMENT // 2 Uint16Array.BYTES_PER_ELEMENT // 2 Int32Array.BYTES_PER_ELEMENT // 4 Uint32Array.BYTES_PER_ELEMENT // 4 Float32Array.BYTES_PER_ELEMENT // 4 Float64Array.BYTES_PER_ELEMENT // 8ArrayBuffer与字符串的互相转换ArrayBuffer转为字符串,或者字符串转为ArrayBuffer,有一个前提,即字符串的编码方法是确定的。假定字符串采用UTF-16编码(JavaScript的内部编码方式),可以自己编写转换函数。// ArrayBuffer转为字符串,参数为ArrayBuffer对象 function ab2str(buf) { return String.fromCharCode.apply(null, new Uint16Array(buf)); } // 字符串转为ArrayBuffer对象,参数为字符串 function str2ab(str) { var buf = new ArrayBuffer(str.length * 2); // 每个字符占用2个字节 var bufView = new Uint16Array(buf); for (var i = 0, strLen = str.length; i < strLen; i++) { bufView[i] = str.charCodeAt(i); } return buf; }TypedArray.prototype.set()TypedArray数组的set方法用于复制数组(正常数组或TypedArray数组),也就是将一段内容完全复制到另一段内存。var a = new Uint8Array(8); var b = new Uint8Array(8); b.set(a);上面代码复制a数组的内容到b数组,它是整段内存的复制,比一个个拷贝成员的那种复制快得多。set方法还可以接受第二个参数,表示从b对象哪一个成员开始复制a对象。var a = new Uint16Array(8); var b = new Uint16Array(10); b.set(a, 2)上面代码的b数组比a数组多两个成员,所以从b[2]开始复制。TypedArray.prototype.subarray()subarray方法是对于TypedArray数组的一部分,再建立一个新的视图。var a = new Uint16Array(8); var b = a.subarray(2,3); a.byteLength // 16 b.byteLength // 2subarray方法的第一个参数是起始的成员序号,第二个参数是结束的成员序号(不含该成员),如果省略则包含剩余的全部成员。所以,上面代码的a.subarray(2,3),意味着b只包含a[2]一个成员,字节长度为2。TypedArray.prototype.slice()TypeArray实例的slice方法,可以返回一个指定位置的新的TypedArray实例。let ui8 = Uint8Array.of(0, 1, 2); ui8.slice(-1) // Uint8Array [ 2 ]上面代码中,ui8是8位无符号整数数组视图的一个实例。它的slice方法可以从当前视图之中,返回一个新的视图实例。slice方法的参数,表示原数组的具体位置,开始生成新数组。负值表示逆向的位置,即-1为倒数第一个位置,-2表示倒数第二个位置,以此类推。TypedArray.of()TypedArray数组的所有构造函数,都有一个静态方法of,用于将参数转为一个TypedArray实例。Float32Array.of(0.151, -8, 3.7) // Float32Array [ 0.151, -8, 3.7 ]TypedArray.from()静态方法from接受一个可遍历的数据结构(比如数组)作为参数,返回一个基于这个结构的TypedArray实例。Uint16Array.from([0, 1, 2]) // Uint16Array [ 0, 1, 2 ]这个方法还可以将一种TypedArray实例,转为另一种。var ui16 = Uint16Array.from(Uint8Array.of(0, 1, 2)); ui16 instanceof Uint16Array // truefrom方法还可以接受一个函数,作为第二个参数,用来对每个元素进行遍历,功能类似map方法。Int8Array.of(127, 126, 125).map(x => 2 * x) // Int8Array [ -2, -4, -6 ] Int16Array.from(Int8Array.of(127, 126, 125), x => 2 * x) // Int16Array [ 254, 252, 250 ]上面的例子中,from方法没有发生溢出,这说明遍历是针对新生成的16位整数数组,而不是针对原来的8位整数数组。也就是说,from会将第一个参数指定的TypedArray数组,拷贝到另一段内存之中(占用内存从3字节变为6字节),然后再进行处理。DataView如果一段数据包括多种类型(比如服务器传来的HTTP数据),这时除了建立ArrayBuffer对象的复合视图以外,还可以通过DataView视图进行操作。DataView视图提供更多操作选项,而且支持设定字节序。本来,在设计目的上,ArrayBuffer对象的各种TypedArray视图,是用来向网卡、声卡之类的本机设备传送数据,所以使用本机的字节序就可以了;而DataView视图的设计目的,是用来处理网络设备传来的数据,所以大端字节序或小端字节序是可以自行设定的。DataView视图本身也是构造函数,接受一个ArrayBuffer对象作为参数,生成视图。DataView(ArrayBuffer buffer [, 字节起始位置 [, 长度]]);下面是一个例子。var buffer = new ArrayBuffer(24); var dv = new DataView(buffer);DataView实例有以下属性,含义与TypedArray实例的同名方法相同。DataView.prototype.buffer:返回对应的ArrayBuffer对象DataView.prototype.byteLength:返回占据的内存字节长度DataView.prototype.byteOffset:返回当前视图从对应的ArrayBuffer对象的哪个字节开始DataView实例提供8个方法读取内存。getInt8:读取1个字节,返回一个8位整数。getUint8:读取1个字节,返回一个无符号的8位整数。getInt16:读取2个字节,返回一个16位整数。getUint16:读取2个字节,返回一个无符号的16位整数。getInt32:读取4个字节,返回一个32位整数。getUint32:读取4个字节,返回一个无符号的32位整数。getFloat32:读取4个字节,返回一个32位浮点数。getFloat64:读取8个字节,返回一个64位浮点数。这一系列get方法的参数都是一个字节序号(不能是负数,否则会报错),表示从哪个字节开始读取。var buffer = new ArrayBuffer(24); var dv = new DataView(buffer); // 从第1个字节读取一个8位无符号整数 var v1 = dv.getUint8(0); // 从第2个字节读取一个16位无符号整数 var v2 = dv.getUint16(1); // 从第4个字节读取一个16位无符号整数 var v3 = dv.getUint16(3);上面代码读取了ArrayBuffer对象的前5个字节,其中有一个8位整数和两个十六位整数。如果一次读取两个或两个以上字节,就必须明确数据的存储方式,到底是小端字节序还是大端字节序。默认情况下,DataView的get方法使用大端字节序解读数据,如果需要使用小端字节序解读,必须在get方法的第二个参数指定true。// 小端字节序 var v1 = dv.getUint16(1, true); // 大端字节序 var v2 = dv.getUint16(3, false); // 大端字节序 var v3 = dv.getUint16(3);DataView视图提供8个方法写入内存。setInt8:写入1个字节的8位整数。setUint8:写入1个字节的8位无符号整数。setInt16:写入2个字节的16位整数。setUint16:写入2个字节的16位无符号整数。setInt32:写入4个字节的32位整数。setUint32:写入4个字节的32位无符号整数。setFloat32:写入4个字节的32位浮点数。setFloat64:写入8个字节的64位浮点数。这一系列set方法,接受两个参数,第一个参数是字节序号,表示从哪个字节开始写入,第二个参数为写入的数据。对于那些写入两个或两个以上字节的方法,需要指定第三个参数,false或者undefined表示使用大端字节序写入,true表示使用小端字节序写入。// 在第1个字节,以大端字节序写入值为25的32位整数 dv.setInt32(0, 25, false); // 在第5个字节,以大端字节序写入值为25的32位整数 dv.setInt32(4, 25); // 在第9个字节,以小端字节序写入值为2.5的32位浮点数 dv.setFloat32(8, 2.5, true);如果不确定正在使用的计算机的字节序,可以采用下面的判断方式。var littleEndian = (function() { var buffer = new ArrayBuffer(2); new DataView(buffer).setInt16(0, 256, true); return new Int16Array(buffer)[0] === 256; })();BlobBlob 对象表示一个不可变、原始数据的类文件对象。Blob 表示的不一定是JavaScript原生格式的数据。File 接口基于Blob,继承了 blob 的功能并将其扩展使其支持用户系统上的文件。要从其他非blob对象和数据构造一个Blob,请使用 Blob() 构造函数。要创建包含另一个blob数据的子集blob,请使用 slice()方法。要获取用户文件系统上的文件对应的Blob对象,请参阅 File文档。从Blob中读取内容的唯一方法是使用 FileReader。以下代码将 Blob 的内容作为类型数组读取:var reader = new FileReader(); reader.addEventListener("loadend", function() { // reader.result 包含转化为类型数组的blob }); reader.readAsArrayBuffer(blob);更多关于Blob的内容,请直接查看这里数据格式转换String转Blob//将字符串 转换成 Blob 对象 var blob = new Blob(["Hello World!"], { type: 'text/plain' }); console.info(blob); console.info(blob.slice(1, 3, 'text/plain'));TypeArray转Blob//将 TypeArray 转换成 Blob 对象 var array = new Uint16Array([97, 32, 72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 33]); //测试成功 //var blob = new Blob([array], ); //测试成功, 注意必须[]的包裹 var blob = new Blob([array]); //将 Blob对象 读成字符串 var reader = new FileReader(); reader.readAsText(blob, 'utf-8'); reader.onload = function (e) { console.info(reader.result); //a Hello world! }ArrayBuffer转Blobvar buffer = new ArrayBuffer(32); var blob = new Blob([buffer]); // 注意必须包裹[]Blob转String这里需要注意的是readAsText方法的使用。//将字符串转换成 Blob对象 var blob = new Blob(['中文字符串'], { type: 'text/plain' }); //将Blob 对象转换成字符串 var reader = new FileReader(); reader.readAsText(blob, 'utf-8'); reader.onload = function (e) { console.info(reader.result); }Blob转ArrayBuffer这里需要注意的是readAsArrayBuffer方法的使用。//将字符串转换成 Blob对象 var blob = new Blob(['中文字符串'], { type: 'text/plain' }); //将Blob 对象转换成 ArrayBuffer var reader = new FileReader(); reader.readAsArrayBuffer(blob); reader.onload = function (e) { console.info(reader.result); //ArrayBuffer //经常会遇到的异常 Uncaught RangeError: byte length of Int16Array should be a multiple of 2 //var buf = new int16array(reader.result); //console.info(buf); //将 ArrayBufferView 转换成Blob var buf = new Uint8Array(reader.result); console.info(buf); //[228, 184, 173, 230, 150, 135, 229, 173, 151, 231, 172, 166, 228, 184, 178] reader.readAsText(new Blob([buf]), 'utf-8'); reader.onload = function () { console.info(reader.result); //中文字符串 }; //将 ArrayBufferView 转换成Blob var buf = new DataView(reader.result); console.info(buf); //DataView reader.readAsText(new Blob([buf]), 'utf-8'); reader.onload = function () { console.info(reader.result); //中文字符串 }; }
2023年09月18日
11 阅读
0 评论
1 点赞
1
2
...
4