帶緩衝的寫並且讀取固定大小byte陣列的物件設計
目前有這樣一個需求,需要多個 goroutine 來寫。多個 goroutine 來讀。但是寫的時候必須組裝成固定大小的 byte 陣列後才能被讀取,否則就等待下一次寫,知道足夠大。
直到關閉物件後,將剩餘的 byte 陣列都放入佇列。
目前設計如下,感覺存在一些問題,請罈子裡的牛人給寫建議,如何設計更優雅呢?
package blob
import (
"sync"
"errors"
"sync/atomic"
)
var ErrClosedBuffer = errors.New("io: read/write on closed buffer")
var ErrBufferNotFull = errors.New("bufio: buffer not full")
type BufferWriterReader struct {
wMu sync.Mutex // Serializes Write operations
buf []byte
n, c int //n 每個byte陣列的大小,c 一共剩餘的佇列長度
wCh chan []byte
size int
done uint32
once sync.Once
}
//從緩衝區中讀取一個陣列,該陣列長度可能會小於設定的緩衝長度
func (p *BufferWriterReader) ReadBytes() (buf []byte, err error) {
//如果緩衝已關閉,佇列已讀完
if atomic.LoadUint32(&p.done) == 1 && p.c == 0 {
return nil, ErrClosedBuffer
}
if p.c > 0 {
err = nil
buf = <-p.wCh
p.c = p.c - 1
} else {
return nil, ErrBufferNotFull
}
return
}
func (p *BufferWriterReader) Write(b []byte) (n int, err error) {
if atomic.LoadUint32(&p.done) == 1 {
return 0, ErrClosedBuffer
}
p.wMu.Lock()
defer p.wMu.Unlock()
//需要將p.buf填滿到指定長度才能放到channel中等待讀取
for once := true; once || len(b) > 0; once = false {
//緩衝區剩餘位元組
l := p.size - p.n
i := 0
if l >= len(b) {
i = copy(p.buf[p.n:], b)
b = b[:0]
} else {
i = copy(p.buf[p.n:], b)
b = b[l+1:]
}
p.n += i
if p.n == p.size {
p.wCh <- p.buf
p.n = 0
p.buf = make([]byte, p.size)
p.c ++
}
if len(b) > 0 {
once = true
}
}
return n, nil
}
func (b *BufferWriterReader) Close() error {
b.once.Do(func() {
//呼叫關閉方法後,將p.buf放入到channel中
atomic.AddUint32(&b.done, 1)
if b.n > 0 {
b.wCh <- b.buf
b.n = 0
b.buf = make([]byte, b.size)
b.c ++
}
close(b.wCh)
})
return nil
}
func NewBufferWriterReaderSize(rSize int, wSize int) *BufferWriterReader {
return &BufferWriterReader{
wMu: sync.Mutex{},
buf: make([]byte, rSize),
wCh: make(chan []byte, wSize),
done: 0,
n: 0,
c: 0,
size: rSize,
}
}
更多原創文章乾貨分享,請關注公眾號
- 加微信實戰群請加微信(註明:實戰群):gocnio
相關文章
- java的byte陣列的不同寫法Java陣列
- Socket程式設計注意接收緩衝區大小程式設計
- Android開發:計算快取大小並且清空快取Android快取
- Request 物件取陣列的方法物件陣列
- java讀取excel為物件並進行讀寫操作JavaExcel物件
- json物件以及陣列鍵值的深度大小寫轉換問題JSON物件陣列
- 陣列合並且去重&向一個陣列新增一條資料(重複的就不新增)&陣列物件去重處理陣列物件
- Duilib的雙緩衝實現,附帶GDI、WTL的雙緩衝實現UI
- 使用 tpl 標籤和 for 讀取物件屬性值中的陣列物件陣列
- 快取與緩衝快取
- 固定容量的本地快取設計快取
- Js陣列物件的屬性值升序排序,並指定陣列中的某個物件移動到陣列的最前面JS陣列物件排序
- byte陣列轉字串?陣列字串
- js 取陣列中某個物件的集合JS陣列物件
- 模擬實現mapreduce中環形緩衝區的讀寫過程
- 固定快取物件快取物件
- Java擷取指定區間內的陣列元素並存入新陣列Java陣列
- C++ 獲取陣列大小、多維陣列操作詳解C++陣列
- C/C++ 讀入一個整型陣列,陣列大小未知C++陣列
- 固定於頂部緩慢下拉且可以定時消失的廣告效果
- 在Python以陣列的方式讀取影像,並轉為Torch張量Python陣列
- Golang併發程式設計有緩衝通道和無緩衝通道(channel)Golang程式設計
- JavaScript WebGL 幀緩衝區物件JavaScriptWeb物件
- 動態更新——緩衝區物件物件
- 什麼?無限緩衝的佇列(一)?佇列
- 什麼?無限緩衝的佇列(二)?佇列
- HDU 3059 Fibonacci數列與矩陣求和 矩陣大小不固定矩陣
- 建立X個任意元素陣列並且可以遍歷的的一個方法陣列
- 如何設定檔案的緩衝
- js,javascript陣列物件的父級物件 – 子集物件(陣列物件相減)JSJavaScript陣列物件
- js如何合併兩個陣列並且刪除重複的元素JS陣列
- Solidity語言學習筆記————13、固定大小位元組陣列Solid筆記陣列
- 用apache JCS實現物件緩衝Apache物件
- 重讀 ES6 — 陣列、物件的擴充套件陣列物件套件
- numpy陣列之讀寫檔案陣列
- 關於利用陣列名獲取陣列大小的一點誤區 - [C&CPP]陣列
- 陣列呼叫c#讀取陣列中獲取最大最小值方法陣列C#
- 如何讀取leetcode中的二維陣列LeetCode陣列