Read string, integers and bytes from file

huangapple go评论190阅读模式
英文:

Read string, integers and bytes from file

问题

我必须使用Go语言读取一个数据被加密的PPM文件(元数据未加密),文件格式如下:

  • "P3" 魔术数字(以字符串形式读取)

  • 图像宽度(以整数形式读取)

  • 图像高度(以整数形式读取)

  • 最大颜色值(以整数形式读取)

然后,我需要读取文件的其余部分,即加密的位,将其作为单个字节数组/切片读取。

例如:

  1. P6
  2. 480 360
  3. 255
  4. �š��GHFHFIGHFHFG~EG~EG~E
  5. ...
  6. HFD{BRRzy|�vxyyhlf%8&NFzx

有什么好的方法可以从文件中读取字符串和整数(前4个元数据值),以及剩余的(加密部分)作为字节?最高效的方法最好,但最简洁(行数最少)的方法更好。

英文:

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.:

  1. P6
  2. 480 360
  3. 255
  4. �š��GHFHFIGHFHFG~EG~EG~E
  5. ...
  6. HFD{BRRzy|�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.

答案1

得分: 1

你可以使用bufio.Reader来读取前三行,使用ReadLineReadString方法,并使用Read方法读取文件的其余部分。

在读取了前三行之后,你可以使用strings包来分割第二行,然后使用strconv包将包含数字的字符串解析为整数。

例如:

  1. r := bufio.NewReader(file)
  2. line1, err := r.ReadString('\n')
  3. if err != nil {
  4. panic(err)
  5. }
  6. // 重复读取第二行和第三行
  7. size := strings.Split(line2, " ")
  8. width, err := strconv.Atoi(size[0])
  9. if err != nil {
  10. panic(err)
  11. }
  12. height, err := strconv.Atoi(size[1])
  13. if err != nil {
  14. panic(err)
  15. }
  16. // 重复处理第三行

更新

Adrian在评论中提到的,你可以使用bufio.Scannerbufio.ScanWordsSplitFunc一起扫描元数据。

  1. s := bufio.NewScanner(r)
  2. s.Split(bufio.ScanWords)
  3. var count int
  4. for s.Scan() && count < 4 {
  5. switch count {
  6. case 0:
  7. magic = s.Text()
  8. case 1:
  9. if width, err = strconv.Atoi(s.Text()); err != nil {
  10. return
  11. }
  12. case 2:
  13. if height, err = strconv.Atoi(s.Text()); err != nil {
  14. return
  15. }
  16. case 3:
  17. if color, err = strconv.Atoi(s.Text()); err != nil {
  18. return
  19. }
  20. }
  21. count++
  22. }

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

英文:

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:

  1. r := bufio.NewReader(file)
  2. line1, err := r.ReadString(&#39;\n&#39;)
  3. if err != nil {
  4. panic(err)
  5. }
  6. // repeat to read line 2 and 3
  7. size := strings.Split(line2, &quot; &quot;)
  8. width, err := strconv.Atoi(size[0])
  9. if err != nil {
  10. panic(err)
  11. }
  12. height, err := strconv.Atoi(size[1])
  13. if err != nil {
  14. panic(err)
  15. }
  16. // 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.

  1. s := bufio.NewScanner(r)
  2. s.Split(bufio.ScanWords)
  3. var count int
  4. for s.Scan() &amp;&amp; count &lt; 4 {
  5. switch count {
  6. case 0:
  7. magic = s.Text()
  8. case 1:
  9. if width, err = strconv.Atoi(s.Text()); err != nil {
  10. return
  11. }
  12. case 2:
  13. if height, err = strconv.Atoi(s.Text()); err != nil {
  14. return
  15. }
  16. case 3:
  17. if color, err = strconv.Atoi(s.Text()); err != nil {
  18. return
  19. }
  20. }
  21. count++
  22. }

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

huangapple
  • 本文由 发表于 2017年5月4日 21:53:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/43784825.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定