附加到 Go 中的文件

问题描述 投票:0回答:8

所以我可以像这样从本地文件中读取:

data, error := ioutil.ReadFile(name)

我可以写入本地文件

ioutil.WriteFile(filename, content, permission)

但是我怎样才能追加到文件中呢?有内置方法吗?

file-io go
8个回答
214
投票

这个答案适用于 Go1:

f, err := os.OpenFile(filename, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
if err != nil {
    panic(err)
}

defer f.Close()

if _, err = f.WriteString(text); err != nil {
    panic(err)
}

75
投票

Go 文档有一个完美的例子

package main

import (
    "log"
    "os"
)

func main() {
    // If the file doesn't exist, create it, or append to the file
    f, err := os.OpenFile("access.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
    if err != nil {
        log.Fatal(err)
    }
    if _, err := f.Write([]byte("appended some data\n")); err != nil {
        log.Fatal(err)
    }
    if err := f.Close(); err != nil {
        log.Fatal(err)
    }
}

33
投票

想通了

更多信息

f, err := os.OpenFile(filename, os.O_APPEND|os.O_WRONLY, 0644) 

n, err := f.WriteString(text) 

f.Close()

8
投票

...我会使用 fmt.Fprintf,因为接受写入器...并且连接或文件将成为写入器并且易于以字符串方式写入...

f, err := os.OpenFile(filename, os.O_APPEND|os.O_WRONLY, 0600)
if err != nil {
    panic(err)
}

defer f.Close()
fmt.Fprintf(f, "%s", text)

我希望这有帮助!

哈维尔,


8
投票
f, err := os.OpenFile(filename, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0644)
if err != nil {
    panic(err)
}

defer f.Close()

if _, err = f.WriteString(text); err != nil {
    panic(err)
}

通过向

os.OpenFile
函数添加标志,对 golang 站点中提供的函数进行了细微更改,该函数默认只允许读取文件,而不允许在其他功能中进行编辑。


6
投票

如果您也想创建文件

f, err := os.OpenFile(filename, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0600)


1
投票

假设您要将文件

current
的内容添加到文件
all
,那么下面的代码就可以工作了:

func updateTrx() {
    var err error
    var f *os.File

    // If the file doesn't exist, create it, or append to the file
    if f, err = os.OpenFile("all.csv", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644); err != nil {
        log.Fatal(err)
    }
    defer func() {
        if err := f.Close(); err != nil {
            log.Fatal("error", err)
        }
    }()

    var current *os.File
    if current, err = os.OpenFile("current.csv", os.O_RDONLY, 0); err != nil {
        log.Fatal("error", err)
    }

    defer func() {
        if err := current.Close(); err != nil {
            log.Fatal("error", err)
        }
    }()

    if fileBytes, err := ioutil.ReadAll(current); err != nil {
        log.Fatal("error", err)
    } else {
        if _, err := f.Write([]byte(fileBytes)); err != nil {
            log.Fatal(err)
        }
    }
}

0
投票

2024:正如m0j0评论中提到的那样,自OP(2011)以来,Go 1.16,2021年第一季度伴随着io/ioutil

弃用

io/ioutil
包已被证明是一个定义不明确且难以理解的东西的集合。
该包提供的所有功能已移至其他包。
io/ioutil
包保留并将继续像以前一样工作,但我们鼓励新代码使用
io
os
包中的新定义。

回到问题:

但是我怎样才能追加到文件中呢?有内置方法吗?

实际上有一个实施这样的方法的提案!
请参阅 2019 年第一季度的提案 30159 和代码 PR 30157

// AppendFile appends data to a file named by filename.
// If the file does not exist, AppendFile creates it with permissions perm.
func AppendFile(filename string, data []byte, perm os.FileMode) error {
    f, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_APPEND, perm)
    if err != nil {
        return err
    }
    n, err := f.Write(data)
    if err == nil && n < len(data) {
        err = io.ErrShortWrite
    }
    if err1 := f.Close(); err == nil {
        err = err1
    }
    return err
}

被拒绝(及其相关问题[30207:提案:cmd/go/internal/lockedfile:添加

Append
功能](https://github.com/golang/go/issues/30207)也被冻结.

伊恩·兰斯·泰勒解释

如果我们添加一个功能

AppendFile
,它必须始终按照人们的期望可靠地工作,无论系统中发生了什么。
使用咨询锁定确实没有帮助 (
flock
)。
使用咨询锁定来处理此问题的程序没有任何问题,但这不能是标准库中名为
AppendFile
的函数。

因此,其他答案在您自己的项目中很好,但在标准库中则不然,如Rob Pike提到

面对并发情况,几乎不可能正确实现这一点,因此向那些可能期望它在这些条件下工作的人提供服务是不明智的。它需要操作系统级语义才能工作,而我们没有。

© www.soinside.com 2019 - 2024. All rights reserved.