如何通过查找切片从切片复制到数组
How to copy from slice to array with seeking onto slice
我正在编写一个库来处理二进制格式。
我有一个带有数组变量的结构,我想保留它用于文档目的。
我还需要从输入的字节片中寻找和分辨。
一些伪代码:
type foo struct {
boo [5]byte
coo [3]byte
}
func main() {
// input is a []byte full of datas, read from a file
var bar foo
// Here i need something that writes 5 bytes to bar.foo from input
bar.foo = somefunc(input, numberOfFoo) // ???
// I need also tell() and seek()
input.seek(n)
}
我怎样才能用一个函数做到这一点?
对字节切片输入进行操作
您可以使用内置函数 copy()
将字节从源切片复制到目标。如果你有一个数组,将它切片以获得一个切片,例如bar.boo[:]
。要寻找,只需在源切片中使用不同的偏移量,也可以通过重新切片,例如input[startPos:]
.
例如:
input := []byte{1, 2, 3, 4, 5, 0, 0, 8, 9, 10}
var bar foo
copy(bar.boo[:], input)
// Skip 2 bytes, seek to the 8th byte:
input = input[7:]
copy(bar.coo[:], input)
fmt.Printf("%+v", bar)
输出(在 Go Playground 上尝试):
{boo:[1 2 3 4 5] coo:[8 9 10]}
创建 ReadSeeker
另一种选择是将您的输入字节片包装成一个 io.ReadSeeker
such as bytes.Reader
,然后您可以从中读取。
例如:
input := []byte{1, 2, 3, 4, 5, 0, 0, 8, 9, 10}
r := bytes.NewReader(input)
var bar foo
if _, err := io.ReadFull(r, bar.boo[:]); err != nil {
panic(err)
}
// Skip 2 bytes, seek to the 8th byte:
if _, err := r.Seek(7, io.SeekStart); err != nil {
panic(err)
}
if _, err := io.ReadFull(r, bar.coo[:]); err != nil {
panic(err)
}
fmt.Printf("%+v", bar)
输出是一样的,在Go Playground.
上试试
使用encoding/binary
另一种解决方案是使用 encoding/binary
一步读取整个结构。
为此,我们需要导出字段,并且我们必须插入一个匿名或空白字段来覆盖跳过的字节:
type foo struct {
Boo [5]byte
_ [2]byte // don't care
Coo [3]byte
}
有了上面的类型,我们可以像这样一步读完:
input := []byte{1, 2, 3, 4, 5, 0, 0, 8, 9, 10}
r := bytes.NewReader(input)
var bar foo
if err := binary.Read(r, binary.LittleEndian, &bar); err != nil {
panic(err)
}
fmt.Printf("%+v", bar)
输出类似,除了它还显示匿名字段(在 Go Playground 上尝试):
{Boo:[1 2 3 4 5] _:[0 0] Coo:[8 9 10]}
查看相关答案:
直接从原始文件读取
您提到您的 input
切片来自读取文件。请注意,您不需要事先读取文件,因为 os.File
implements io.Reader
,甚至 io.ReadSeeker
,这意味着您可以直接从中读取文件,请参阅 Creating a ReadSeeker
节。您也可以直接应用 encoding/binary
解决方案,因为我们在该解决方案中也使用了 reader。
我正在编写一个库来处理二进制格式。
我有一个带有数组变量的结构,我想保留它用于文档目的。
我还需要从输入的字节片中寻找和分辨。
一些伪代码:
type foo struct {
boo [5]byte
coo [3]byte
}
func main() {
// input is a []byte full of datas, read from a file
var bar foo
// Here i need something that writes 5 bytes to bar.foo from input
bar.foo = somefunc(input, numberOfFoo) // ???
// I need also tell() and seek()
input.seek(n)
}
我怎样才能用一个函数做到这一点?
对字节切片输入进行操作
您可以使用内置函数 copy()
将字节从源切片复制到目标。如果你有一个数组,将它切片以获得一个切片,例如bar.boo[:]
。要寻找,只需在源切片中使用不同的偏移量,也可以通过重新切片,例如input[startPos:]
.
例如:
input := []byte{1, 2, 3, 4, 5, 0, 0, 8, 9, 10}
var bar foo
copy(bar.boo[:], input)
// Skip 2 bytes, seek to the 8th byte:
input = input[7:]
copy(bar.coo[:], input)
fmt.Printf("%+v", bar)
输出(在 Go Playground 上尝试):
{boo:[1 2 3 4 5] coo:[8 9 10]}
创建 ReadSeeker
另一种选择是将您的输入字节片包装成一个 io.ReadSeeker
such as bytes.Reader
,然后您可以从中读取。
例如:
input := []byte{1, 2, 3, 4, 5, 0, 0, 8, 9, 10}
r := bytes.NewReader(input)
var bar foo
if _, err := io.ReadFull(r, bar.boo[:]); err != nil {
panic(err)
}
// Skip 2 bytes, seek to the 8th byte:
if _, err := r.Seek(7, io.SeekStart); err != nil {
panic(err)
}
if _, err := io.ReadFull(r, bar.coo[:]); err != nil {
panic(err)
}
fmt.Printf("%+v", bar)
输出是一样的,在Go Playground.
上试试使用encoding/binary
另一种解决方案是使用 encoding/binary
一步读取整个结构。
为此,我们需要导出字段,并且我们必须插入一个匿名或空白字段来覆盖跳过的字节:
type foo struct {
Boo [5]byte
_ [2]byte // don't care
Coo [3]byte
}
有了上面的类型,我们可以像这样一步读完:
input := []byte{1, 2, 3, 4, 5, 0, 0, 8, 9, 10}
r := bytes.NewReader(input)
var bar foo
if err := binary.Read(r, binary.LittleEndian, &bar); err != nil {
panic(err)
}
fmt.Printf("%+v", bar)
输出类似,除了它还显示匿名字段(在 Go Playground 上尝试):
{Boo:[1 2 3 4 5] _:[0 0] Coo:[8 9 10]}
查看相关答案:
直接从原始文件读取
您提到您的 input
切片来自读取文件。请注意,您不需要事先读取文件,因为 os.File
implements io.Reader
,甚至 io.ReadSeeker
,这意味着您可以直接从中读取文件,请参阅 Creating a ReadSeeker
节。您也可以直接应用 encoding/binary
解决方案,因为我们在该解决方案中也使用了 reader。