Golang:file.Seek和file.WriteAt没有按预期工作

时间:2016-07-28 09:13:52

标签: go file-writing

我正在尝试制作一个程序,该程序在文件中提供偏移量,就像我可以从第20个偏移量开始写入等。

这是我用作参考的示例代码之一

package main

import (
    "fmt"
    "io/ioutil"
    "os"
)

const (
    filename   = "sample.txt"
    start_data = "12345"
)

func printContents() {
    data, err := ioutil.ReadFile(filename)
    if err != nil {
        panic(err)
    }
    fmt.Println("CONTENTS:", string(data))
}

func main() {
    err := ioutil.WriteFile(filename, []byte(start_data), 0644)
    if err != nil {
        panic(err)
    }

    printContents()

    f, err := os.OpenFile(filename, os.O_RDWR, 0644)
    if err != nil {
        panic(err)
    }
    defer f.Close()

    if _, err := f.Seek(20, 0); err != nil {
        panic(err)
    }

    if _, err := f.WriteAt([]byte("A"), 15); err != nil {
        panic(err)
    }

    printContents()
}

但我总是得到相同的文件内容,从开始就像

12345A

我尝试将搜索值随机改为(0,0)和(20,0)和(10,1),这会产生相同的输出

此外,我尝试将 WriteAt偏移量更改为其他偏移量,例如10,20,但这也导致相同。

我想获得一个解决方案,以便我可以在文件中的任何指定位置写入,建议我在此代码中出错。

1 个答案:

答案 0 :(得分:5)

按预期工作。

运行代码后,“sample.txt”文件内容为(16字节):

[49 50 51 52 53 0 0 0 0 0 0 0 0 0 0 65]

尝试:

package main

import (
    "fmt"
    "io/ioutil"
)

const (
    filename   = "sample.txt"
    start_data = "12345"
)

func printContents() {
    data, err := ioutil.ReadFile(filename)
    if err != nil {
        panic(err)
    }
    fmt.Println(data)
}

func main() {
    printContents()
}

首先需要写足够的字节,使用WriteAt偏移量:
例如编辑:

start_data = "1234567890123456789012345678901234567890"

然后测试你的代码:

package main

import (
    "fmt"
    "io/ioutil"
    "os"
)

const (
    filename   = "sample.txt"
    start_data = "1234567890123456789012345678901234567890"
)

func printContents() {
    data, err := ioutil.ReadFile(filename)
    if err != nil {
        panic(err)
    }
    fmt.Println(string(data))
}

func main() {
    err := ioutil.WriteFile(filename, []byte(start_data), 0644)
    if err != nil {
        panic(err)
    }

    printContents()

    f, err := os.OpenFile(filename, os.O_RDWR, 0644)
    if err != nil {
        panic(err)
    }
    defer f.Close()

    if _, err := f.Seek(20, 0); err != nil {
        panic(err)
    }

    if _, err := f.WriteAt([]byte("A"), 15); err != nil {
        panic(err)
    }

    printContents()
}

输出:

1234567890123456789012345678901234567890
123456789012345A789012345678901234567890