gpt4 book ai didi

go - Go 中的问题,附加到 []byte,写入文件并读取它

转载 作者:数据小太阳 更新时间:2023-10-29 03:45:44 26 4
gpt4 key购买 nike

我正在尝试解析大量 IP(约 20mb 或 400 万个 IP),将它们作为字节存储在文件中,稍后再读取。

我遇到的问题是我希望它们按排序顺序存储,但我看到随机 byte slice ,在读回它们时看起来像损坏的 IP。

//让它叫做generator.go

var buf []byte


// So this is where we build up `buf`, which we later write to a file.
func writeOut(record RecordStruct) {
// This line is never hit. All slices have a length of 4, as expected
if len(record.IPEnd.Bytes()) != 4 {
fmt.Println(len(record.IPEnd.Bytes()), record.IPEnd.Bytes())
}

// Let's append the IP to the byte slice with a seperater of 10 null bytes which we will later call bytes.Split on.
buf = append(buf, append(record.IPEnd.Bytes(), bytes.Repeat([]byte{0}, 10)...)...)
}

func main () {
// Called many times. For brevity I won't include all of that logic.
// There are no Goroutines in the code and running with -race says all is fine.

writeOut(...)

err := ioutil.WriteFile("bin/test", buf, 0644)
}

阅读器.go

func main() {
bytez, err := ioutil.ReadFile("bin/test")

if err != nil {
fmt.Println("Asset was not found.")
}

haystack := bytes.Split(bytez, bytes.Repeat([]byte{0}, 10))

for _, needle := range haystack {
// Get's hit maybe 10% of the time. The logs are below.
if len(needle) != 4 {
fmt.Println(fmt.Println(needle))
}
}
}
[188 114 235]
14 <nil>
[120 188 114 235 121]
22 <nil>
[188 148 98]
13 <nil>
[120 188 148 98 121]
21 <nil>

如您所见,不是 IP 太少就是太多。

如果我更改日志以更好地说明问题,看起来最后一个八位字节溢出了?

Fine: [46 36 202 235]
Fine: [46 36 202 239]
Fine: [46 36 202 255]
Weird: [46 36 203]
Weird: [0 46 36 203 1]
Fine: [46 36 203 3]
Fine: [46 36 203 5]
Fine: [46 36 203 7]
Fine: [46 36 203 9]

最佳答案

当 IP 地址以零字节结尾时,代码无法正确拆分字节。通过 converting the address to 16 byte representation 修复并存储无分隔符的 16 字节记录。

您可以使用以下方法高效地将 v4 和 v6 地址的混合附加到缓冲区:

switch len(p) {
case net.IPv6len:
buf = append(buf, p...)
case net.IPv4len:
buf = append(buf, v4InV6Prefix...)
buf = append(buf, p...)
default:
// handle error
}

其中 v4InV6Prefix 是一个包级变量,值为 []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff.

以 v6 地址读取文件:

 buf, err := ioutil.ReadFile(xxx)
if err != nil {
// handle error
}
for i := 0; i < len(buf); i += 16 {
addr := net.IP(buf[i:i+16])
// do something with addr
}

请注意,也可以使用 io.Reader 和 io.Writer 以增量方式读取和写入文件。此答案中的代码与应用程序一次性读取和写入文件的问题中的代码匹配。

关于go - Go 中的问题,附加到 []byte,写入文件并读取它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57529122/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com