2022-09-19 encoding/binary與bytes包配合使用

binary與bytes包配合使用

1.bytes.Reader

bytes.Reader是一個實現(xiàn)了io.Reader接口的結(jié)構(gòu)體,用于方便從指定的切片中讀取數(shù)據(jù)吠卷。

可以從一個已有的切片構(gòu)造bytes.Reader,方便讀寫切片个唧。

構(gòu)造:

func NewReader(b []byte) *Reader

操作:

func (r *Reader) Read(b []byte) (n int, err error)

Reader從底層切片中到目標(biāo)切片b中钥顽,讀取數(shù)量為b的大小坟冲,如果不夠讀取源切片全部數(shù)據(jù)睛挚,返回讀取到的字節(jié)數(shù)量邪蛔。

2.bytes.Buffer

該接口是實現(xiàn)了io.Reader和io.Writer接口的字節(jié)緩。

構(gòu)造:

//方法1:根據(jù)指定的切片構(gòu)造Buffer
func NewBuffer(buf []byte) *Buffer
//方法2:直接構(gòu)造空Buffer
buf := new(bytes.Buffer)

使用:

//從buffer中讀取len(p)大小的數(shù)據(jù)
func (b *Buffer) Read(p []byte) (n int, err error)
//往buffer中寫入p切片中的數(shù)據(jù)
func (b *Buffer) Write(p []byte) (n int, err error)

3.binary.Read

從r中讀取binary編碼的數(shù)據(jù)并賦給data扎狱,data必須是一個指向定長值的指針或者定長值的切片侧到。

原型:

func Read(r io.Reader, order ByteOrder, data interface{}) error

參數(shù)1:實現(xiàn)io.Reader接口的結(jié)構(gòu)

參數(shù)2:大小端字節(jié)序

參數(shù)3:要從r中讀取到的二進制數(shù)據(jù)保存到data變量中

如果有錯誤返回error

使用:

bytes.Reader結(jié)構(gòu)實現(xiàn)了io.Reader接口勃教,所以可以使用binary.Read從bytes.Reader中讀取二進制切片數(shù)據(jù)到指定data變量中。

var pi float64
b := []byte{0x18, 0x2d, 0x44, 0x54, 0xfb, 0x21, 0x09, 0x40}
Reader := bytes.NewReader(b)
err := binary.Read(Reader, binary.LittleEndian, &pi)
if err != nil {
    fmt.Println("binary.Read failed:", err)
}
fmt.Print(pi)

4.binary.Write

把data數(shù)據(jù)按照指定的字節(jié)序?qū)懙絯中匠抗,w是實現(xiàn)了io.Writer接口的類型故源。

原型:

func Write(w io.Writer, order ByteOrder, data interface{}) error

參數(shù)1:w是實現(xiàn)了io.Writer接口類型的數(shù)據(jù)。

參數(shù)2:大小端字節(jié)序

參數(shù)3: 把data變量中的二進制數(shù)據(jù)寫到w中汞贸。

使用:

bytes.Buffer結(jié)構(gòu)實現(xiàn)了io.Reader,io.Writer接口绳军,所以可以使用binary.Write()將data變量的數(shù)據(jù),寫入到buffer中矢腻。

buf := new(bytes.Buffer)
var pi float64 = math.Pi
err := binary.Write(buf, binary.LittleEndian, pi)
//將pi寫入到buffer中
if err != nil {
    fmt.Println("binary.Write failed:", err)
}
fmt.Printf("% x", buf.Bytes())

example

//server
package main
import (
    "bytes"
    "encoding/binary"
    "fmt"
    "log"
    "net"
    "unsafe"
)
func init() {
    log.SetFlags(log.Lshortfile)
}
type MessageHeader struct {
    MessageType   int32
    MessageLength int32
}
func Handle(conn net.Conn) {
    //處理連接的讀寫
    message_header := MessageHeader{}
//go語言的sizeof參數(shù)是實例出的對象的大小门驾,不能傳類型,跟C++不同
    bin_data := make([]byte, unsafe.Sizeof(message_header))
    _, err := conn.Read(bin_data)
    if err != nil {
        log.Println("conn.Read,error", err)
        return
    }
    //創(chuàng)建一個基于bin_data的Bytes.Reader
    reader := bytes.NewReader(bin_data)
    //把讀到的數(shù)據(jù)寫入header中
    err = binary.Read(reader, binary.LittleEndian, &message_header)
    if err != nil {
        log.Println("binary.Read error = ", err)
        return
    }
    fmt.Println(message_header)
    conn.Write(bin_data)
}
func main() {
    listenner, err := net.Listen("tcp", "127.0.0.1:9000")
    if err != nil {
        log.Fatalln("net.Listen error:=", err)
    }
    for {
        conn, err := listenner.Accept()
        if err != nil {
            log.Println("listenner.Accept() error:=", err)
            continue
        }
        go Handle(conn)
    }
}
//client
package main
import (
    "bytes"
    "encoding/binary"
    "fmt"
    "log"
    "net"
    "time"
    "unsafe"
)
type MessageHeader struct {
    MessageType   int32 //這里有個坑多柑,請不要定義int類型奶是,否則binary解析會有問題,因為int大小根據(jù)平臺而定竣灌,不是定長的
    MessageLength int32
}
func init() {
    log.SetFlags(log.Lshortfile)
}
func main() {
    conn, err := net.Dial("tcp", "127.0.0.1:9000")
    if err != nil {
        log.Panicln("net.Dial errr,", err)
    }
    buffer := new(bytes.Buffer)
    header := &MessageHeader{
        MessageType:   1,
        MessageLength: 20,
    }
    err = binary.Write(buffer, binary.LittleEndian, header)
    if err != nil {
        log.Println("binary.Write err,", err)
        return
    }
    _, err = conn.Write(buffer.Bytes())
    if err != nil {
        log.Println("conn.Wirte err,", err)
        return
    }
    bin_data := make([]byte, unsafe.Sizeof(header))
    conn.Read(bin_data)
    target := &MessageHeader{}
    reader := bytes.NewReader(bin_data)
    binary.Read(reader, binary.LittleEndian, target)
    fmt.Println(target)
    time.Sleep(time.Second * 5)
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末聂沙,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子初嘹,更是在濱河造成了極大的恐慌逐纬,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,542評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件削樊,死亡現(xiàn)場離奇詭異豁生,居然都是意外死亡,警方通過查閱死者的電腦和手機漫贞,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,596評論 3 385
  • 文/潘曉璐 我一進店門甸箱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人迅脐,你說我怎么就攤上這事芍殖。” “怎么了谴蔑?”我有些...
    開封第一講書人閱讀 158,021評論 0 348
  • 文/不壞的土叔 我叫張陵豌骏,是天一觀的道長。 經(jīng)常有香客問我隐锭,道長窃躲,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,682評論 1 284
  • 正文 為了忘掉前任钦睡,我火速辦了婚禮蒂窒,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己洒琢,他們只是感情好秧秉,可當(dāng)我...
    茶點故事閱讀 65,792評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著衰抑,像睡著了一般象迎。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上呛踊,一...
    開封第一講書人閱讀 49,985評論 1 291
  • 那天砾淌,我揣著相機與錄音,去河邊找鬼恋技。 笑死拇舀,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的蜻底。 我是一名探鬼主播骄崩,決...
    沈念sama閱讀 39,107評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼薄辅!你這毒婦竟也來了要拂?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,845評論 0 268
  • 序言:老撾萬榮一對情侶失蹤站楚,失蹤者是張志新(化名)和其女友劉穎脱惰,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體窿春,經(jīng)...
    沈念sama閱讀 44,299評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡拉一,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,612評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了旧乞。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蔚润。...
    茶點故事閱讀 38,747評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖尺栖,靈堂內(nèi)的尸體忽然破棺而出嫡纠,到底是詐尸還是另有隱情,我是刑警寧澤延赌,帶...
    沈念sama閱讀 34,441評論 4 333
  • 正文 年R本政府宣布除盏,位于F島的核電站,受9級特大地震影響挫以,放射性物質(zhì)發(fā)生泄漏者蠕。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,072評論 3 317
  • 文/蒙蒙 一屡贺、第九天 我趴在偏房一處隱蔽的房頂上張望蠢棱。 院中可真熱鬧锌杀,春花似錦甩栈、人聲如沸泻仙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,828評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽玉转。三九已至,卻和暖如春殴蹄,著一層夾襖步出監(jiān)牢的瞬間究抓,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,069評論 1 267
  • 我被黑心中介騙來泰國打工袭灯, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留刺下,地道東北人。 一個月前我還...
    沈念sama閱讀 46,545評論 2 362
  • 正文 我出身青樓稽荧,卻偏偏與公主長得像橘茉,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子姨丈,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,658評論 2 350

推薦閱讀更多精彩內(nèi)容