从io.ReadWriteSeeker删除字节(通过文件)

时间:2018-10-09 23:11:01

标签: go

假设我有一个io.ReadWriteSeeker,它正在从某个文件中读取文字。

在某个时候,我决定要从文件(特别是末尾)中删除一些字节并减小其长度。

解决这个问题的正确方法是什么?

  • 我不能仅仅通过搜索来覆盖它,因为我想以一个较短的文件结尾。

  • io.CopyN同样无法工作(因为src小于dest)

1 个答案:

答案 0 :(得分:0)

如果io.ReadWriteSeeker值也支持Truncate方法,例如* os.File值。

例如,

package main

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

func truncate(rws io.ReadWriteSeeker, size int64) error {
    type Truncater interface {
        Truncate(size int64) error
    }
    t, ok := rws.(Truncater)
    if !ok {
        return fmt.Errorf("truncate: unable to truncate")
    }
    return t.Truncate(size)
}

func main() {
    filename := `/tmp/truncate.test.file`
    f, err := os.Create(filename)
    if err != nil {
        fmt.Fprintln(os.Stderr, err)
        return
    }
    defer f.Close()
    n, err := f.Write([]byte("test data"))
    if err != nil {
        fmt.Fprintln(os.Stderr, err)
        return
    }
    data, err := ioutil.ReadFile(filename)
    if err != nil {
        fmt.Fprintln(os.Stderr, err)
        return
    }
    fmt.Println(string(data))

    // truncate io.ReadWriteSeeker
    err = truncate(f, int64(n-1))
    if err != nil {
        fmt.Fprintln(os.Stderr, err)
        return
    }

    data, err = ioutil.ReadFile(filename)
    if err != nil {
        fmt.Fprintln(os.Stderr, err)
        return
    }
    fmt.Println(string(data))
    os.Remove(filename)
}

游乐场:https://play.golang.org/p/pp4IUSoKo4M

输出:

test data
test dat