Go语言base64流式编码在收尾时的一个小坑

2024-03-27 00:52

本文主要是介绍Go语言base64流式编码在收尾时的一个小坑,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

问题复现

请看下面代码

sb := strings.Builder{}
_, err := io.Copy(base64.NewEncoder(base64.StdEncoding, &sb),bytes.NewBufferString("12345678"),
)
if err != nil {panic(err)
}
fmt.Println("编码后:", sb.String())
data, err := base64.StdEncoding.DecodeString(sb.String())
if err != nil {panic(err)
}
fmt.Println("解码后:", string(data))

这里利用io.Copy将任意io.Reader编码为base64字符串,这种写法在处理网络通信等流式数据时十分简洁高效。可是,以上代码运行结果如下:

编码后: MTIzNDU2
解码后: 123456

显见,末尾的78被丢掉了。

原因分析

base64结尾处使用===标记编码未满,因此流式编码器在不知道当前是否为文件末尾时,不会贸然写入===,而是统一以3字节组进行编码,将不满3字节的写入数据残余部分先暂存起来。
  这样做是因为每3字节原始数据正好对应4字节base64编码,而完整的base64编码并不包含===,因此可以直接写入接收端。
  为了适配流式编码,base64.NewEncoder返回的并不是io.Writer而是io.WriteCloser。我们必须要显式调用其Close方法以通知编码器写入结尾残余部分,否则当原始数据长度不是3的倍数时,将在结尾处出现结尾缺损。

解决方案

编码结束后调用流式编码器的Close方法。

sb := strings.Builder{}
enc := base64.NewEncoder(base64.StdEncoding, &sb)
_, err := io.Copy(enc,bytes.NewBufferString("12345678"),
)
if err != nil {panic(err)
}
err = enc.Close()
if err != nil {panic(err)
}
fmt.Println("编码后:", sb.String())
data, err := base64.StdEncoding.DecodeString(sb.String())
if err != nil {panic(err)
}
fmt.Println("解码后:", string(data))

此时,输出恢复正常。

编码后: MTIzNDU2Nzg=
解码后: 12345678

这篇关于Go语言base64流式编码在收尾时的一个小坑的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/850424

相关文章

Java中流式并行操作parallelStream的原理和使用方法

《Java中流式并行操作parallelStream的原理和使用方法》本文详细介绍了Java中的并行流(parallelStream)的原理、正确使用方法以及在实际业务中的应用案例,并指出在使用并行流... 目录Java中流式并行操作parallelStream0. 问题的产生1. 什么是parallelS

从基础到高级详解Go语言中错误处理的实践指南

《从基础到高级详解Go语言中错误处理的实践指南》Go语言采用了一种独特而明确的错误处理哲学,与其他主流编程语言形成鲜明对比,本文将为大家详细介绍Go语言中错误处理详细方法,希望对大家有所帮助... 目录1 Go 错误处理哲学与核心机制1.1 错误接口设计1.2 错误与异常的区别2 错误创建与检查2.1 基础

Go语言中json操作的实现

《Go语言中json操作的实现》本文主要介绍了Go语言中的json操作的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录 一、jsOChina编程N 与 Go 类型对应关系️ 二、基本操作:编码与解码 三、结构体标签(Struc

java读取excel文件为base64实现方式

《java读取excel文件为base64实现方式》文章介绍使用ApachePOI和EasyExcel处理Excel文件并转换为Base64的方法,强调EasyExcel适合大文件且内存占用低,需注意... 目录使用 Apache POI 读取 Excel 并转换为 Base64使用 EasyExcel 处

Python动态处理文件编码的完整指南

《Python动态处理文件编码的完整指南》在Python文件处理的高级应用中,我们经常会遇到需要动态处理文件编码的场景,本文将深入探讨Python中动态处理文件编码的技术,有需要的小伙伴可以了解下... 目录引言一、理解python的文件编码体系1.1 Python的IO层次结构1.2 编码问题的常见场景二

python语言中的常用容器(集合)示例详解

《python语言中的常用容器(集合)示例详解》Python集合是一种无序且不重复的数据容器,它可以存储任意类型的对象,包括数字、字符串、元组等,下面:本文主要介绍python语言中常用容器(集合... 目录1.核心内置容器1. 列表2. 元组3. 集合4. 冻结集合5. 字典2.collections模块

使用Go调用第三方API的方法详解

《使用Go调用第三方API的方法详解》在现代应用开发中,调用第三方API是非常常见的场景,比如获取天气预报、翻译文本、发送短信等,Go作为一门高效并发的编程语言,拥有强大的标准库和丰富的第三方库,可以... 目录引言一、准备工作二、案例1:调用天气查询 API1. 注册并获取 API Key2. 代码实现3

基于Go语言开发一个 IP 归属地查询接口工具

《基于Go语言开发一个IP归属地查询接口工具》在日常开发中,IP地址归属地查询是一个常见需求,本文将带大家使用Go语言快速开发一个IP归属地查询接口服务,有需要的小伙伴可以了解下... 目录功能目标技术栈项目结构核心代码(main.go)使用方法扩展功能总结在日常开发中,IP 地址归属地查询是一个常见需求:

Java中字符编码问题的解决方法详解

《Java中字符编码问题的解决方法详解》在日常Java开发中,字符编码问题是一个非常常见却又特别容易踩坑的地方,这篇文章就带你一步一步看清楚字符编码的来龙去脉,并结合可运行的代码,看看如何在Java项... 目录前言背景:为什么会出现编码问题常见场景分析控制台输出乱码文件读写乱码数据库存取乱码解决方案统一使

C++右移运算符的一个小坑及解决

《C++右移运算符的一个小坑及解决》文章指出右移运算符处理负数时左侧补1导致死循环,与除法行为不同,强调需注意补码机制以正确统计二进制1的个数... 目录我遇到了这么一个www.chinasem.cn函数由此可以看到也很好理解总结我遇到了这么一个函数template<typename T>unsigned