英文:
Read string, integers and bytes from file
问题
我必须使用Go语言读取一个数据被加密的PPM文件(元数据未加密),文件格式如下:
-
"P3" 魔术数字(以字符串形式读取)
-
图像宽度(以整数形式读取)
-
图像高度(以整数形式读取)
-
最大颜色值(以整数形式读取)
然后,我需要读取文件的其余部分,即加密的位,将其作为单个字节数组/切片读取。
例如:
P6
480 360
255
�š��GHFHFI�GHFHFG~EG~EG~E
...
HFD{BR�Rz�y|�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.:
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.
答案1
得分: 1
你可以使用bufio.Reader来读取前三行,使用ReadLine或ReadString方法,并使用Read方法读取文件的其余部分。
在读取了前三行之后,你可以使用strings包来分割第二行,然后使用strconv包将包含数字的字符串解析为整数。
例如:
r := bufio.NewReader(file)
line1, err := r.ReadString('\n')
if err != nil {
panic(err)
}
// 重复读取第二行和第三行
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)
}
// 重复处理第三行
更新:
如Adrian在评论中提到的,你可以使用bufio.Scanner和bufio.ScanWords的SplitFunc
一起扫描元数据。
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
英文:
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('\n')
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++
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论