使用Golang进行读取的mmap系统调用

时间:2017-06-13 04:21:58

标签: file go io system-calls mmap

我不是一个不安全的包装专家 - 我也不是一名经验丰富的C程序员。我正在尝试阅读一个巨大的文件> 1G使用mmap系统调用go。我做mmap和munmap有很多原因,而不是读取,写入I / O.这是重点 - 我可以在测试中写入文件,当我从文件中读取时,我可以确定字节长度匹配,但我无法读取此字符串文件的内容:(有人可以建议阅读吗?我需要做的更进一步,这里是我为样品测试做的一些代码:

filename := "/tmp/dd_file.db"
f, err := os.OpenFile(filename, os.O_RDWR, 0666)
defer f.Close()
if err != nil {
    fmt.Printf("error opening file: %v", err)
}
stat, _ := f.Stat()
size := stat.Size()
fmt.Printf("[READ-ONLY] : size was : %+v\n", size)
got := make([]byte, size)
if _, err := f.ReadAt(got, 0); err != nil && err != io.EOF {
    panic(err)
}
want, err := ioutil.ReadFile(filename)
if err != nil {
    fmt.Printf("[READ-ONLY] : ioutil.ReadFile: %v", err)
}
// going to change the file size now, punch in a few things
t := unsafe.Sizeof("")
if err != nil {
    fmt.Println(err)
    os.Exit(1)
}
_, err = f.Seek(int64(t-1), 0)
if err != nil {
    fmt.Println(err)
    os.Exit(1)
}
_, err = f.Write([]byte(" "))
if err != nil {
    fmt.Println(err)
    os.Exit(1)
}
mmap, err := syscall.Mmap(int(f.Fd()), 0, int(t), syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_SHARED)
if err != nil {
    fmt.Println(err)
    os.Exit(1)
}
 // not too sure on reading data on string - doesnt work as expected.
map_array := (*[10000]string)(unsafe.Pointer(&mmap[0]))
map_array[0] = "yellow!"
err = syscall.Munmap(mmap)
if err != nil {
    fmt.Println(err)
    os.Exit(1)
}
newStat, _ := f.Stat()
newSize := newStat.Size()
fmt.Printf("[mmap( ) RW] : size was : %+v\n", newSize)
got = make([]byte, newSize)
if _, err := f.ReadAt(got, 0); err != nil && err != io.EOF {
    panic(err)
}
if len(got) == len(want) {
    fmt.Println("well the lengths are equal atleast??!")
}
if !bytes.Equal(got, want) {
    fmt.Printf("\n [mmap( ) RW] : works! got  %d \n want %d", len(got), len(want))
}

这显然可以正常工作 - 但是如果我想在mmapped文件上通过mmap()读取,如何从这些字节中读取字符串(我感觉有一个编码包,我可能需要也许使用但是然后StringHeader对不安全的文档感到困惑。)

建议。

1 个答案:

答案 0 :(得分:0)

正如@putu在注释中指出的那样,可以通过简单的类型转换将字节切片转换为字符串:

asStr = string(byteSlice) // entire slice as a string
partStr = string(byteSlice[:100]) // first 100 bytes as a string