为了账号安全,请及时绑定邮箱和手机立即绑定

从前面截断缓冲区

从前面截断缓冲区

Go
梦里花落0921 2021-06-30 16:00:06
该bytes.Buffer对象有一个Truncate(n int)方法可以丢弃除第一个n字节之外的所有字节。我需要完全相反的 - 保留最后一个 n字节。我可以做到以下几点b := buf.Bytes()buf.Reset()buf.Write(b[offset:])但我不确定这是否会有效地重用切片。有更好的选择吗?
查看完整描述

3 回答

?
慕的地10843

TA贡献1785条经验 获得超8个赞

有两种选择:

  • 您提供的解决方案允许重用第一个“偏移”字节。

  • 创建一个 bytes.NewBuffer(b[offset:]) 并使用它。这将不允许在您完成新缓冲区之前收集第一个“偏移”字节,但它避免了复制成本。


查看完整回答
反对 回复 2021-07-12
?
一只萌萌小番薯

TA贡献1795条经验 获得超7个赞

我认为你的想法的问题在于“从一开始就截断缓冲区”是不可能的,因为内存分配器以完整的块分配内存,并且其中没有机器将已分配的块拆分为一组“子块”-基本上就是你所要求的。因此,为了支持“从头修剪”的实现,bytes.Buffer必须分配一个较小的缓冲区,将“尾部”移到那里,然后标记原始缓冲区以供重用。

这自然使我们想到另一个想法:使用两个(或更多)缓冲区。他们可能要么被分别分配和处理相邻你algorythms或者您可以使用自定义的分配:分配一个大截,然后重新划分两次或更多次,以产生几个物理相邻的缓冲区,或幻灯片的一个或多个“窗口”片在它. 这当然意味着实现自定义数据结构......


查看完整回答
反对 回复 2021-07-12
?
ABOUTYOU

TA贡献1812条经验 获得超5个赞

让我们bytes.Buffer处理缓冲区管理。内部grow方法将数据向下滑动。使用Next方法。例如,


package main


import (

    "bytes"

    "fmt"

)


func main() {

    var buf bytes.Buffer

    for i := 0; i < 8; i++ {

        buf.WriteByte(byte(i))

    }

    fmt.Println(buf.Len(), buf.Bytes())

    n := buf.Len() / 2


    // Keep last n bytes.

    if n > buf.Len() {

        n = buf.Len()

    }

    buf.Next(buf.Len() - n)


    fmt.Println(buf.Len(), buf.Bytes())

}

输出:


8 [0 1 2 3 4 5 6 7]

4 [4 5 6 7]


查看完整回答
反对 回复 2021-07-12
  • 3 回答
  • 0 关注
  • 186 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信