帶緩衝的寫並且讀取固定大小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
相關文章
- 寫個方法近似計算指定陣列或物件佔用記憶體的大小陣列物件記憶體
- json物件以及陣列鍵值的深度大小寫轉換問題JSON物件陣列
- 緩衝帶裡的少年
- java讀取excel為物件並進行讀寫操作JavaExcel物件
- 陣列合並且去重&向一個陣列新增一條資料(重複的就不新增)&陣列物件去重處理陣列物件
- 帶緩衝的輸入/輸入流
- Duilib的雙緩衝實現,附帶GDI、WTL的雙緩衝實現UI
- 固定容量的本地快取設計快取
- Js陣列物件的屬性值升序排序,並指定陣列中的某個物件移動到陣列的最前面JS陣列物件排序
- js 取陣列中某個物件的集合JS陣列物件
- 在Python以陣列的方式讀取影像,並轉為Torch張量Python陣列
- C++ 獲取陣列大小、多維陣列操作詳解C++陣列
- Java擷取指定區間內的陣列元素並存入新陣列Java陣列
- C/C++ 讀入一個整型陣列,陣列大小未知C++陣列
- JS 獲取陣列物件的值&提取Object的valueJS陣列物件Object
- Solidity語言學習筆記————13、固定大小位元組陣列Solid筆記陣列
- 如何讀取leetcode中的二維陣列LeetCode陣列
- 陣列的reduce操作+物件陣列的map操作陣列物件
- Golang併發程式設計有緩衝通道和無緩衝通道(channel)Golang程式設計
- 易語言帶陣列json的編寫方法陣列JSON
- JavaScript WebGL 幀緩衝區物件JavaScriptWeb物件
- 什麼?無限緩衝的佇列(一)?佇列
- 什麼?無限緩衝的佇列(二)?佇列
- 建立X個任意元素陣列並且可以遍歷的的一個方法陣列
- while迴圈和do迴圈、緩衝區、一維陣列While陣列
- python如何獲取陣列元素的下標並輸出Python陣列
- numpy陣列之讀寫檔案陣列
- 物件陣列與一般陣列的區別物件陣列
- Golang 陣列和字串之間的相互轉換[]byte/stringGolang陣列字串
- Javascript中的陣列物件排序JavaScript陣列物件排序
- JS 中特殊的物件-陣列JS物件陣列
- 重寫陣列的方法(改變原陣列)陣列
- Javascript 物件 – 陣列物件JavaScript物件陣列
- Rust 程式設計,讀取命令列引數Rust程式設計命令列
- 【效能技巧】使用DataReader[列序號]的方法讀取DataReader物件物件
- js 去掉陣列物件中的重複物件JS陣列物件
- pandas.DataFrame讀取特定的列並刪除某列空值所在的行
- Java併發程式設計:4種執行緒池和緩衝佇列BlockingQueueJava程式設計執行緒佇列BloC