我需要提取字节缓冲区中的各个字段。我想出了以下解决方案:
func (fs *FileSystem) readSB() { // fs.f is a *os.File buf := make([]byte, 1024) fs.f.ReadAt(buf, 1024) // Offset: type var p *bytes.Buffer // 0: uint32 p = bytes.NewBuffer(buf[0:]) binary.Read(p, binary.LittleEndian, &fs.sb.inodeCount) // 4: uint32 p = bytes.NewBuffer(buf[4:]) binary.Read(p, binary.LittleEndian, &fs.sb.blockCount) // 20: uint32 p = bytes.NewBuffer(buf[20:]) binary.Read(p, binary.LittleEndian, &fs.sb.firstDataBlock) // 24: uint32 p = bytes.NewBuffer(buf[24:]) binary.Read(p, binary.LittleEndian, &fs.sb.blockSize) fs.sb.blockSize = 1024 << fs.sb.blockSize // 32: uint32 p = bytes.NewBuffer(buf[32:]) binary.Read(p, binary.LittleEndian, &fs.sb.blockPerGroup) // 40: uint32 p = bytes.NewBuffer(buf[40:]) binary.Read(p, binary.LittleEndian, &fs.sb.inodePerBlock) }
有没有更好/惯用/直接的方法呢?
通过使用.Next()跳过不想读取的字节,可以避免每次创建新缓冲区:
.Next()
{ // Offset: type p := bytes.NewBuffer(buf) // 0: uint32 binary.Read(p, binary.LittleEndian, &fs.sb.inodeCount) // 4: uint32 binary.Read(p, binary.LittleEndian, &fs.sb.blockCount) // Skip [8:20) p.Next(12) // 20: uint32 binary.Read(p, binary.LittleEndian, &fs.sb.firstDataBlock) // 24: uint32 binary.Read(p, binary.LittleEndian, &fs.sb.blockSize) fs.sb.blockSize = 1024 << fs.sb.blockSize // Skip [28:32) p.Next(4) // 32: uint32 binary.Read(p, binary.LittleEndian, &fs.sb.blockPerGroup) // Skip [36:40) p.Next(4) // 40: uint32 binary.Read(p, binary.LittleEndian, &fs.sb.inodePerBlock) }
或者,您可以避免逐块阅读,而创建一个标头结构,您可以使用binary.Read以下方法直接读取它:
binary.Read
type Head struct { InodeCount uint32 // 0:4 BlockCount uint32 // 4:8 Unknown1 uint32 // 8:12 Unknown2 uint32 // 12:16 Unknown3 uint32 // 16:20 FirstBlock uint32 // 20:24 BlockSize uint32 // 24:28 Unknown4 uint32 // 28:32 BlocksPerGroup uint32 // 32:36 Unknown5 uint32 // 36:40 InodesPerBlock uint32 // 40:44 } func main() { var header Head err = binary.Read(file, binary.LittleEndian, &header) if err != nil { log.Fatal(err) } log.Printf("%#v\n", header) }