目录
在 Go 语言中,encoding
标准库提供了多种用于数据编码和解码的包,如 asn1
、base64
、binary
、json
、xml
等。下面我将分别介绍这些包的基本使用方法。
base64
encoding/base64
包用于处理 Base64 编码,这是一种常见的用于在文本中表示二进制数据的编码方式。
package main
import (
"encoding/base64"
"fmt"
)
func main() {
input := "hello world"
// 编码
enc := base64.StdEncoding.EncodeToString([]byte(input))
fmt.Println("Encoded:", enc)
// 解码
dec, err := base64.StdEncoding.DecodeString(enc)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println("Decoded:", string(dec))
}
base64原理:
binary
encoding/binary
包用于处理二进制数据的编码和解码,支持固定大小的数据结构。
package main
import (
"bytes"
"encoding/binary"
"fmt"
)
func main() {
buf := bytes.NewBuffer([]byte{})
binary.Write(buf, binary.BigEndian, int32(1000))
fmt.Println(buf.Bytes())
var num int32
binary.Read(buf, binary.BigEndian, &num)
fmt.Println(num)
}
另一个例子:
package main
import (
"bytes"
"encoding/binary"
"fmt"
)
func main() {
// 创建一个新的字节缓冲
buf := bytes.NewBuffer([]byte{})
buf2 := bytes.NewBuffer([]byte{})
// 写入各种数据类型
binary.Write(buf, binary.BigEndian, int64(1000))
binary.Write(buf, binary.BigEndian, float32(123.456))
binary.Write(buf, binary.BigEndian, float64(789.0123))
// 写入字符串需要先转为字节数组
str := "╬~皿~"
runes := []rune(str)
buf3 := new(bytes.Buffer)
err := binary.Write(buf3, binary.BigEndian, runes)
if err != nil {
fmt.Println("binary.Write failed:", err)
return
}
fmt.Println(buf3.Bytes())
binary.Write(buf2, binary.BigEndian, []byte(str))
// 读取 int64
var num1 int64
binary.Read(buf, binary.BigEndian, &num1)
fmt.Println("int64:", num1)
// 读取 float32
var num2 float32
binary.Read(buf, binary.BigEndian, &num2)
fmt.Println("float32:", num2)
// 读取 float64
var num3 float64
binary.Read(buf, binary.BigEndian, &num3)
fmt.Println("float64:", num3)
// 读取字符串
bytesStr := make([]byte, len(str))
binary.Read(buf2, binary.BigEndian, &bytesStr)
fmt.Println("string:", string(bytesStr))
}
需要知道,go中string是UTF-8编码已经能满足中文,但是要更大的字符集需要rune。
json
encoding/json
包用于处理 JSON 数据格式的编码和解码。
package main
import (
"encoding/json"
"fmt"
"os"
)
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
}
func main() {
p := Person{"Bob", 25}
data, err := json.Marshal(p)
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %v", err)
return
}
fmt.Println(string(data))
var newP Person
json.Unmarshal(data, &newP)
fmt.Println(newP)
}
xml
encoding/xml
包类似于 encoding/json
,但用于处理 XML 数据。
package main
import (
"encoding/xml"
"fmt"
"os"
)
type Person struct {
XMLName xml.Name `xml:"person"`
Name string `xml:"name"`
Age int `xml:"age"`
}
func main() {
p := Person{Name: "Alice", Age: 30}
data, err := xml.MarshalIndent(p, "", " ")
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %v", err)
return
}
fmt.Println(string(data))
var newP Person
xml.Unmarshal(data, &newP)
fmt.Println(newP)
}
CSV
CSV (Comma-Separated Values) 是一种常见的文本文件格式,用于存储表格数据。encoding/csv
包可以方便地读取和写入 CSV 文件。
package main
import (
"encoding/csv"
"os"
"fmt"
)
func main() {
records := [][]string{
{"name", "age"},
{"Alice", "30"},
{"Bob", "25"},
}
file, err := os.Create("data.csv")
if err != nil {
fmt.Println("Error:", err)
return
}
defer file.Close()
writer := csv.NewWriter(file)
writer.WriteAll(records) // 写入多行记录
if err := writer.Error(); err != nil {
fmt.Println("Error:", err)
}
}
GOB
GOB 是 Go 自己的二进制格式,用于在 Go 程序之间传输数据结构。encoding/gob
包提供了编码和解码 GOB 数据的功能。
package main
import (
"bytes"
"encoding/gob"
"fmt"
)
type Person struct {
Name string
Age int
}
func main() {
var buf bytes.Buffer
enc := gob.NewEncoder(&buf)
dec := gob.NewDecoder(&buf)
p := Person{"Alice", 30}
enc.Encode(p)
var newP Person
dec.Decode(&newP)
fmt.Println(newP)
}
HEX
HEX 格式常用于将二进制数据以十六进制字符串的形式表示。encoding/hex
包提供了对 HEX 编码和解码的支持。
package main
import (
"encoding/hex"
"fmt"
)
func main() {
src := []byte("hello world")
encodedStr := hex.EncodeToString(src)
fmt.Println("Encoded:", encodedStr)
decodedBytes, err := hex.DecodeString(encodedStr)
if err != nil {
fmt.Println("Decode error:", err)
return
}
fmt.Println("Decoded:", string(decodedBytes))
}
PEM
PEM (Privacy Enhanced Mail) 格式是一种将加密密钥或证书存储为 ASCII 编码的格式。encoding/pem
包用于编码和解码 PEM 数据。
package main
import (
"encoding/pem"
"os"
"fmt"
)
func main() {
block := &pem.Block{
Type: "MY CERTIFICATE",
Bytes: []byte("your certificate data here"),
}
file, err := os.Create("certificate.pem")
if err != nil {
fmt.Println("Error:", err)
return
}
defer file.Close()
err = pem.Encode(file, block)
if err != nil {
fmt.Println("Error:", err)
}
}
总结
在 Go 语言中,通过 encoding
标准库及其子包,我们可以高效地处理多种数据格式,每种格式均有其特定用途:
- ASN.1:适用于处理复杂的数据结构,常用于安全和网络协议中。
- Base64:用于在文本中表示二进制数据,广泛用于数据编解码。
- Binary:直接以二进制形式读写固定大小的数据,用于低层数据操作。
- JSON:处理现代网络通信中普遍使用的数据格式,易于数据交换。
- XML:用于标记化的数据表示,常见于配置文件和网络服务。
- CSV:用于读写简单的表格数据,广泛应用于数据导入导出。
- GOB:Go 特有的二进制格式,优化了同语言间的数据结构传输。
- HEX:将二进制数据表示为十六进制字符串,用于编码和调试。
- PEM:处理加密密钥和证书,关键于安全领域。
通过掌握这些工具,Go 程序员可以灵活地在多种应用场景中处理和传输数据,从而提高开发效率和系统性能。这些技术的深入理解和妥善使用,是每位 Go 开发者技能提升的关键。