Работа на входе байтового слайса
Вы можете использовать встроенный 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
, например 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
для чтения всей структуры за один шаг.
InЧтобы сделать это, нам нужно экспортировать поля, и мы должны вставить анонимное или пустое поле, которое охватывает пропущенные байты:
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
реализует io.Reader
, даже io.ReadSeeker
, что означает, что вы можете читать из него напрямую, см. Создание раздела ReadSeeker
.Вы также можете напрямую применить решение encoding/binary
, поскольку в этом решении мы также использовали ридер.