golang:从文件中读取字符串,整数和字节

I have to read a PPM file with its data encrypted (metadata is not encrypted), using Go, and the file format is given to me containing:

  • The "P3" magic number (read as string)

  • Image width (read as integer)

  • Image height (read as integer)

  • Maximum color value (read as integer)

Then, I need to read the rest of the file is the encrypted bits, which I have to read as a single byte array/slice.

e.g.:

P6
480 360
255
�š��GHFHFI�GHFHFG~EG~EG~E
...
HFD{BR�Rz�y|�vxyyhlf%8&NFzx

What is a good way to read string and integers (the 4 initial metadata values) and the rest (encrypted part) as bytes from the file? It can be the most efficient, but the cleanest (less lines) is preferred.

You can use bufio.Reader to read the first 3 lines using the ReadLine or ReadString method and reading the rest of the file using the Read method.

After you've read the first 3 lines you can use the strings package to split the second line, and then the strconv package to parse the strings containing numbers as integers.

For example:

r := bufio.NewReader(file)
line1, err := r.ReadString('
')
if err != nil {
    panic(err)
}
// repeat to read line 2 and 3

size := strings.Split(line2, " ")
width, err := strconv.Atoi(size[0])
if err != nil {
    panic(err)
}
height, err := strconv.Atoi(size[1])
if err != nil {
    panic(err)
}
// repeat with line 3

Update:

As mentioned in the comments by Adrian you can use bufio.Scanner together with the bufio.ScanWord SplitFunc to scan for the metadata.

s := bufio.NewScanner(r)
s.Split(bufio.ScanWords)

var count int
for s.Scan() && count < 4 {
    switch count {
    case 0:
        magic = s.Text()
    case 1:
        if width, err = strconv.Atoi(s.Text()); err != nil {
            return
        }
    case 2:
        if height, err = strconv.Atoi(s.Text()); err != nil {
            return
        }
    case 3:
        if color, err = strconv.Atoi(s.Text()); err != nil {
            return
        }
    }
    count++
}

https://play.golang.org/p/-rOJb_WlFf