临沂网站制作页面/常用的seo查询工具
文章目录
- 一:简介
- 二:Go标准库compress/gzip包介绍
- Constants
- Variables
- type Header
- type Reader
- 三:代码实践
- 1、压缩与解压工具包
- 2、单元测试
- 3、为何压缩后还要用base64编码
代码地址: https://gitee.com/lymgoforIT/golang-trick/tree/master/41-go-gzip
一:简介
在工作中,我们有时候需要用到Redis
来缓存数据,减轻DB
的压力,并提升访问性能。但是当要缓存的key
数据过大了会带来BigKey
问题:30.Go处理Redis BigKey
在介绍BigKey
问题的影响和解决办法时,我们其实说过,最好的办法是预防BigKey
的出现,而不是出现后去解决。
但有些场景要缓存的一条信息内容可能就是比较大,且无法拆分,这时候怎么办呢?那就压缩后再存入Redis
吧。
二:Go标准库compress/gzip包介绍
compress/gzip是Go标准库中的一个压缩工具包,中文文档地址:https://studygolang.com/static/pkgdoc/pkg/compress_gzip.htm
gzip
包实现了gzip
格式压缩文件的读写,核心内容如下。
-
Constants:常量定义
-
Variables:变量定义
-
type Header:数据头结构
-
type Reader:解压
- func NewReader(r io.Reader) (*Reader, error)
- func (z *Reader) Reset(r io.Reader) error
- func (z *Reader) Read(p []byte) (n int, err error)
- func (z *Reader) Close() error
-
type Writer:压缩
- func NewWriter(w io.Writer) *Writer
- func NewWriterLevel(w io.Writer, level int) (*Writer, error)
- func (z *Writer) Reset(w io.Writer)
- func (z *Writer) Write(p []byte) (int, error)
- func (z *Writer) Flush() error
- func (z *Writer) Close() error
Constants
const (NoCompression = flate.NoCompression // 不压缩BestSpeed = flate.BestSpeed // 最快速度BestCompression = flate.BestCompression // 最佳压缩比DefaultCompression = flate.DefaultCompression // 默认压缩比
)
这些常量都是拷贝自flate
包,因此导入"compress/gzip"
后,就不必再导入"compress/flate"
了。
Variables
var (// 当读取的gzip数据的校验和错误时,会返回ErrChecksumErrChecksum = errors.New("gzip: invalid checksum")// 当读取的gzip数据的头域错误时,会返回ErrHeaderErrHeader = errors.New("gzip: invalid header")
)
type Header
//数据头结构
type Header struct {Comment string // 文件注释Extra []byte // 附加数据ModTime time.Time // 文件修改时间Name string // 文件名OS byte // 操作系统类型
}
gzip
文件保存一个头域,提供关于被压缩的文件的一些元数据。该头域作为Writer
和Reader
类型的一个可导出字段,可以提供给调用者访问。
type Reader
type Reader struct {Header// 内含隐藏或非导出字段
}
Reader
类型满足io.Reader
接口,可以从gzip
格式压缩文件读取并解压数据。
一般情况下,一个gzip
文件可以是多个gzip
文件的串联,每一个都有自己的头域。从Reader
读取数据会返回串联的每个文件的解压数据,但只有第一个文件的头域被记录在Reader
的Header
字段里。
gzip
文件会保存未压缩前数据的长度与校验和。当读取到未压缩数据的结尾时,如果数据的长度或者校验和不正确,Reader
会返回ErrCheckSum
,如果没有读取完毕后,长度和校验和与压缩前数据的一致,说明解压成功。因此,调用者应该将Read
方法返回的数据视为暂定的,直到他们在数据结尾获得了一个io.EOF
。
func NewReader
func NewReader(r io.Reader) (*Reader, error)
NewReader
返回一个从r
读取并解压数据的Reader
。其实现会缓冲输入流的数据,并可能从r
中读取比需要的更多的数据(如长度和校验和)。调用者有责任在读取完毕后调用返回值的Close
方法。
注意入参是io.Reader,返回值是*gzip.Reader,但*gzip.Reader(Struct)也是实现了io.Reader接口的
func (*Reader) Reset
func (z *Reader) Reset(r io.Reader) error
Reset
将z
重置,丢弃当前的读取状态,并将下层读取目标设为r
。效果上等价于将z
设为使用r
重新调用NewReader
返回的Reader。这让我们可以重用z
而不是再申请一个新的。(因此效率更高)
func (*Reader) Read
func (z *Reader) Read(p []byte) (n int, err error)
func (*Reader) Close
func (z *Reader) Close() error
调用Close
会关闭z
,但不会关闭下层io.Reader
接口。
type Writer
type Writer struct {Header// 内含隐藏或非导出字段
}
Writer
满足io.WriteCloser
接口。它会将提供给它的数据压缩后写入下层io.Writer
接口。
func NewWriter
func NewWriter(w io.Writer) *Writer
NewWriter
创建并返回一个Writer
。写入返回值gzip.Writer
的数据都会在压缩后写入入参指定的w
中。调用者有责任在结束写入后调用返回值gzip.Writer的Close方法。因为写入的数据可能保存在缓冲中没有刷新入下层。
如要设定Writer.Header
字段,调用者必须在第一次调用Write
方法或者Close
方法之前设置。Header
字段的Comment
和Name
字段是go
的utf-8
字符串,但下层格式要求为NUL
中止的ISO 8859-1 (Latin-1)
序列。如果这两个字段的字符串包含NUL
或非Latin-1
字符,将导致Write
方法返回错误。
func NewWriterLevel
func NewWriterLevel(w io.Writer, level int) (*Writer, error)
NewWriterLevel
类似NewWriter
但指定了压缩水平而不是采用默认的DefaultCompression
。
参数level
可以是DefaultCompression、NoCompression
或BestSpeed
与BestCompression
之间的任何整数。如果level
合法,返回的错误值为nil
。
func (*Writer) Reset
func (z *Writer) Reset(dst io.Writer)
Reset
将z
重置,丢弃当前的写入状态,并将下层输出目标设为dst
。效果上等价于将w
设为使用dst
和w
的压缩水平重新调用NewWriterLevel
返回的*Writer
。这让我们可以重用z
而不是再申请一个新的。(因此效率更高)
func (*Writer) Write
func (z *Writer) Write(p []byte) (int, error)
Write
将p
压缩后写入下层io.Writer
接口。压缩后的数据不一定会立刻刷新,除非Writer被关闭或者显式的刷新,即调用Close方法或者Flush方法。
func (*Writer) Flush
func (z *Writer) Flush() error
Flush
将缓冲中的压缩数据刷新到下层io.Writer
接口中。
本方法主要用在传输压缩数据的网络连接中,以保证远端的接收者可以获得足够的数据来重构数据报。Flush
会阻塞直到所有缓冲中的数据都写入下层io.Writer
接口后才返回。如果下层的io.Writetr
接口返回一个错误,Flush
也会返回该错误。在zlib
包的术语中,Flush
方法等价于Z_SYNC_FLUSH
。
func (*Writer) Close
func (z *Writer) Close() error
调用Close
会关闭z
,但不会关闭下层io.Writer
接口。
三:代码实践
1、压缩与解压工具包
package utilimport ("bytes""compress/gzip""context""encoding/base64""fmt"
)// GzipEncode 采用gzip算法压缩字符串,输出base64编码的字符串
func GzipEncode(ctx context.Context, input string) (string, error) {if len(input) == 0 {return input, nil}var b bytes.Buffer // 实现了io.Writergz := gzip.NewWriter(&b)defer func() {if err := gz.Close(); err != nil {fmt.Println(fmt.Sprintf("gz.Close() err:%v", err))}}()if _, err := gz.Write([]byte(input)); err != nil {fmt.Println(fmt.Sprintf("[GzipEncode] gz write err:%v", err))return "", err}// 将gzip.Writer缓冲中的数据刷到底层io.Writer中if err := gz.Flush(); err != nil {fmt.Println(fmt.Sprintf("[GzipEncode] gz flush err:%v", err))return "", err}// 在读取数据之前必须close,否则读取的数据会有问题,在这里作用同Flush一样// 即将压缩后的数据立即写入底层io.Writer中,在这里是b(bytes.Buffer)if err := gz.Close(); err != nil {fmt.Println(fmt.Sprintf("[GzipEncode] gz close err:%v", err))return "", err}newStr := base64.StdEncoding.EncodeToString(b.Bytes())return newStr, nil
}// GzipDecode 采用gzip算法解压字符串
func GzipDecode(ctx context.Context, input string) (string, error) {newInput, err := base64.StdEncoding.DecodeString(input)if err != nil {fmt.Println(fmt.Sprintf("[GzipDecode] base decode err:%v", err))return "", err}bReader := bytes.NewReader(newInput)gReader, err := gzip.NewReader(bReader)if err != nil {fmt.Println(fmt.Sprintf("[GzipDecode] new reader err,%v", err))return "", err}if err = gReader.Close(); err != nil {fmt.Println(fmt.Sprintf("[GzipDecode] reader close err:%v", err))return "", err}buf := new(bytes.Buffer)if _, err = buf.ReadFrom(gReader); err != nil {fmt.Println(fmt.Sprintf("[GzipDecode] read from greader err:%v", err))return "", err}return buf.String(), err
}
2、单元测试
package utilimport ("context""fmt""testing"
)func TestGzipEncode(t *testing.T) {encode, err := GzipEncode(context.Background(), "hello world")if err != nil {fmt.Println(fmt.Sprintf("GzipEncode err:%v", err))return}fmt.Println(fmt.Sprintf("res:%v", encode))
}func TestGzipDecode(t *testing.T) {decode, err := GzipDecode(context.Background(), "H4sIAAAAAAAA/8pIzcnJVyjPL8pJAQAAAP//AQAA//+FEUoNCwAAAA==")if err != nil {fmt.Println(fmt.Sprintf("GzipEncode err:%v", err))return}fmt.Println(fmt.Sprintf("res:%v", decode))
}
当执行TestGzipEncode
后,我们可以看到输出为
当执行TestGzipDecode
后,可以看到输出为
测试结果符合预期。
此时可能会有一个疑问,一个hello world
压缩并用base64
编码后,字符串长度更长了,这不是与压缩的初衷背道而驰了嘛?是的,这里只是为了演示,所以用了个hello world
,实际场景下,既然选择了压缩,那肯定是已知要压缩的内容是比较大的。
比如我们稍微将字符串变长一些,看看效果就知道压缩对于减少内存占用确实是有用的
3、为何压缩后还要用base64编码
我们可以将util
中的源代码去掉base64
编码后,单元测试一下看看原始gzip
压缩后,字符串会是什么形式呢?
可以看到压缩后字符串确实很小了,但是美观,且复制后对其解压会报错GzipEncode err:unexpected EOF
,所以还是把base64
编码用上吧!!
相关文章:

69.使用Go标准库compress/gzip压缩数据存入Redis避免BigKey
文章目录 一:简介二:Go标准库compress/gzip包介绍ConstantsVariablestype Headertype Reader 三:代码实践1、压缩与解压工具包2、单元测试3、为何压缩后还要用base64编码 代码地址: https://gitee.com/lymgoforIT/golang-trick/t…...

JavaScript实现的一些小案例
小案例 灯开关案例 <body><img id"light" src"img/off.jpg"><script>var light document.getElementById("light");var flag false;if(flag){light.src "img/on.jpg";flag false;}else{light.src "img/…...

MVC模式
Model-View-Controller : 模型-视图-控制器模式,用于应用程序的分层开发。 Model(模型):代表一个存取数据的对象。也可以带有逻辑,在数据变化时更新控制器。 View(视图):代表模型包含的数据的可视化。 Controller(控制器)…...

Java中的代理模式(一)
大家好👋,我是极客涛😎,今天我们聊一聊java中的代理模式,话不多说,还是老思路,什么是代理模式,为什么要有代理模式,如何实现代理模式 代理模式 在说java中的代理模式之前…...

跳跃游戏-算法
题目 给定一个数组nums {1,2,3,4,5},每个元素nums[i]表示从i这个位置最多可以向前跳跃nums[i]个台阶,求最小需要跳几次就可以调到末尾 思路 反向查找 从末尾开始逐个向前判断最远的起跳位置,接着再以该位置递归的判断 public int jumpT…...

ERP系统哪个好用?用友,金蝶,ORACLE,SAP综合测评
ERP系统哪个好用?用友,金蝶,ORACLE,SAP综合测评 ERP领域SAP、ORACLE相对于国内厂商如用友、金蝶优势在哪? SAP,ORACLE操作习惯一般国人用不惯;相对于国产软件,界面也很难看&#x…...

外汇天眼:美国证券交易委员会(SEC)采纳了一系列规定,以加强与特殊目的收购公司(SPACs)相关的投资者保护
美国证券交易委员会(SEC)今天通过了一系列新规和修订,以增强特殊目的收购公司(SPACs)的首次公开募股(IPOs)中的披露,并在SPACs与目标公司之间的后续业务合并交易(de-SPAC…...

kotlin map 与 flatmap
kotlin map 与 flatmap 是2个不同的概念的 map 是一种数据结构,flatmap 是一个高阶函数,处理集合用的 Map Map 是一种数据结构,它由一系列的键值对组成,每个键都是唯一的,并且与一个特定的值相关联。你可以通过键来…...

nginx-rtmp-module 支持 Enhancing RTMP HEVC(H.265)
Enhancing RTMP, FLV 2023年7月31号正式发布,主要支持了HEVC(H.265)、VP9、AV1视频编码,发布差不多半年了,很多开源项目已支持,最近打算播放和推送端也支持下,想找个支持的rtmp server方便测试用,但没找到合…...

2024最新JDK1.8+JDK17+JDK21安装包下载+文档
2024年更新,JDK8的64位和32位安装包都有,Java8最新文档也有,JDK17和JDK21的最新安装包也有 因为网上的安装包都不是最新的,所以自己去Oracle官网登录下载保存了一份,需要的朋友下面网盘链接下载 JDK8—64位安装程序&…...

如何利用chatgpt提升工作效率
chatgpt全领域小助手 项目管理:制定项目计划、跟踪进度、分配任务和记录里程碑。客户服务:回答常见问题、提供产品支持和处理客户投诉,提升客户满意度。销售支持:提供销售培训、销售脚本和客户资料,辅助销售团队进行销…...

WinSCP下载安装并实现远程SSH本地服务器上传文件
文章目录 1. 简介2. 软件下载安装:3. SSH链接服务器4. WinSCP使用公网TCP地址链接本地服务器5. WinSCP使用固定公网TCP地址访问服务器 1. 简介 Winscp是一个支持SSH(Secure SHell)的可视化SCP(Secure Copy)文件传输软件,它的主要功能是在本地与远程计…...

QEMU搭建arm虚拟机开发环境
获取QEMU代码 git clone https://gitlab.com/qemu-project/qemu.git 切换对应的工程分支 使用git指令切换到对应的分支上,我这里使用的是stable-4.0的分支 git checkout -b stable-4.0 remotes/origin/stable-4.0 配置&编译 在工程的根目录下执行 ./conf…...

web 应用常见的安全问题
一xss攻击 人们经常将跨站脚本攻击(Cross Site Scripting)缩写为CSS,但这会与层叠样式表(Cascading Style Sheets,CSS)的缩写混淆。因此,有人将跨站脚本攻击缩写为XSS。 跨站脚本攻击ÿ…...

502. IPO
502. IPO 题目链接:502. IPO 代码如下: //堆的使用 class Solution { public:int findMaximizedCapital(int k, int w, vector<int>& profits, vector<int>& capital) {vector<pair<int,int>> mp;//优先队列默认的是大…...

如何安装MeterSphere并实现无公网ip远程访问服务管理界面
文章目录 前言1. 安装MeterSphere2. 本地访问MeterSphere3. 安装 cpolar内网穿透软件4. 配置MeterSphere公网访问地址5. 公网远程访问MeterSphere6. 固定MeterSphere公网地址 正文开始前给大家推荐个网站,前些天发现了一个巨牛的 人工智能学习网站, 通…...

做FP独立站怎么引流?这个引流法宝收好了!
近年来,由于卖家数量飙升导致平台竞争持续升级,卖家之间的恶性循环竞争以及平台政策的不断调整等,造成了众多亚马逊等跨境卖家纷纷从平台转向独立站。可是,转型做独立站前要先考虑清楚独立站与平台二者之间的区别。 如果在第三方平…...

幻兽帕鲁PalWorld服务器搭建教程,1分钟开服,纯小白教程,无需基础
雨云面板服快速开幻兽帕鲁PalWorld服务器的教程,配置文件修改方法和配置项中文注释。 最近这游戏挺火,很多人想跟朋友联机,如果有专用服务器,就不需要房主一直开着电脑,稳定性也好得多。 幻兽帕鲁简介 《幻兽帕鲁》…...

算法小抄01
1. 计数排序是一种基于 统计 的排序算法 2. 基于比较的排序算法有:(1)直接插入排序;(2)冒泡排序;(3)简单选择排序;(4)希尔排序&#…...

Spring Boot 集成 API 文档 - Swagger、Knife4J、Smart-Doc
文章目录 1.OpenAPI 规范2.Swagger: 接口管理的利器3.Swagger 与 SpringFox:理念与实现4.Swagger 与 Knife4J:增强与创新5.案例:Spring Boot 整合 Swagger35.1 引入 Swagger3 依赖包5.2 优化路径匹配策略兼容 SpringFox5.3 配置 Swagger5.4 S…...

2024年软考报名时间及条件,小白必看
不少考生开始准备报名2024年软件水平考试,那么报名软考有没有学历、专业以及工作经验等方面的限制呢?今天就给大家梳理下2024年软考考试,若有变更,也会及时更新内容。 免费送备考资料。联系我 2024年软考考试时间 2024年软考有两次考试&a…...

vue 跨域XMLHttpRequest
vue 跨域 使用XMLHttpRequest 亲测好使 let url=http://127.0.0.1:9000/pssnotifyyb?b=1//url=https://api.j4u.ink/v1/store/other/proxy/remote/moyu.jsonvar xhr=new XMLHttpRequest()xhr.open(GET,url,true)//第三个参数是是否异步请求,默认true xhr.onreadyst…...

【正点原子STM32】STM32基础知识(F1F4F7H7 STM32系统框架、寻址范围、存储器映射的存储器功能划分、寄存器映射)
一、STM32系统框架 1.1、Cortex M内核 & 芯片1.2、F1系统架构1.3、F4系统架构1.4、F7系统架构1.5、H7系统架构 二、STM32的寻址范围? 三、存储器映射 存储器功能划分(F1为例)STM32F1存储器映射图 四、寄存器映射 寄存器基础知识STM3…...

Oracle、MySQL数据库常规命令语法-简易记录(非常规持续更新)
前言:呈现的是非常基础必备命令以及常规关联语法,因涉及到不同数据库其表达都会有所区别,此篇纯属做个仓库记录更非常规持续更新,专业人士可忽略,且看且珍惜… MySQL: 关系型数据库、重点开源、支持大型规模、标准SQL数据语言、多平台多架构、高可用集群、可定制开发等等、…...

用react搞定一个大模型对话效果
怎么用react实现一个类似文心一言那样的对话效果呢? 最近AI盛行,关注几个大模型网站都能发现,跟AI对话的时候,返回的文本是逐字展示的,就给人一种AI边解析边返回的感觉(不知道是为了装X还是真的需要这样&a…...

DP读书:在常工院的2023年度总结
DarrenPig的年度总结 这是最好的时代,这是最坏的时代。——狄更斯 这是最好的时代,这是最坏的时代。——狄更斯 这是最好的时代,这是最坏的时代。——狄更斯 一、2023我的感受 不就是2023吗,不就是一年的经历吗,大家…...

2023-2024年重庆职业院校技能大赛“信息安全管理与评估”比赛样题
2023 年重庆职业院校技能大赛(高等职业教育) “信息安全管理与评估”样题任务书 第一阶段:任务 1 网络平台搭建(50 分)任务 2 网络安全设备配置与防护(250 分) 第二阶段:第一部分 网…...

【Ubuntu】systemctl 命令
systemctl 是一个用于检视和控制 systemd 系统和服务管理器的命令行工具。systemd 是用于启动、停止和管理 Linux 系统中的服务的守护进程。以下是一些常用的 systemctl 命令及其说明: systemctl start <unit>: 启动指定的服务单元 systemctl start sshd sy…...

xinput1_3.dll文件的几种修复办法以及修复xinput1_3.dll注意事项
xinput1_3.dll文件是DirectX的一部分,它在Windows系统中负责处理游戏控制器的输入。然而,有时候此文件可能会出现问题,导致游戏无法正常运行或启动。在本文中,将介绍多种解决xinput1_3.dll文件问题的方法,并对它们进行…...

javaWebssh宠物基地管理系统myeclipse开发mysql数据库MVC模式java编程计算机网页设计
一、源码特点 java ssh宠物基地管理系统是一套完善的web设计系统(系统采用ssh框架进行设计开发),对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用 B/S模式开发。开发环境为TOMCAT7.…...