在 Go 中追加到文件

发布于 2024-11-30 14:21:35 字数 207 浏览 1 评论 0 原文

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

data, error := ioutil.ReadFile(name)

并且我可以写入本地文件

ioutil.WriteFile(filename, content, permission)

但是如何附加到文件?有内置方法吗?

So I can read from a local file like so:

data, error := ioutil.ReadFile(name)

And I can write to a local file

ioutil.WriteFile(filename, content, permission)

But how can I append to a file? Is there a built in method?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

甜点 2024-12-07 14:21:35

这个答案适用于 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)
}

This answers works in 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)
}
汐鸠 2024-12-07 14:21:35

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)
    }
}

Go docs has a perfect example :

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)
    }
}
檐上三寸雪 2024-12-07 14:21:35

弄清楚了

详细信息

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

n, err := f.WriteString(text) 

f.Close()

Figured it out

More info

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

n, err := f.WriteString(text) 

f.Close()
枕梦 2024-12-07 14:21:35
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 站点中提供的函数进行了轻微更改,该函数默认只允许读取文件,而不允许在其他功能中进行编辑。

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)
}

Made a slight change from the one provided in the golang site by adding flags to the os.OpenFile function which by default will only allow reading of a file and not editing amongst other features.

眼眸 2024-12-07 14:21:35

...我会使用 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)

我希望这有所帮助!

哈维尔,

... I would use fmt.Fprintf, because accept a writer... and a connection or files will be a writer and easy to write in a way of string...

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)

I hope this help!

Javier,

那一片橙海, 2024-12-07 14:21:35

如果您还想创建文件

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

If you also want to create the file

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

不必你懂 2024-12-07 14:21:35

假设您要将文件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)
        }
    }
}

Let's say you want to add the contents of filecurrent to the file all, then below code is working:

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)
        }
    }
}
最终幸福 2024-12-07 14:21:35

2024:如 m0j0 -a-file-in-go?noredirect=1#comment139306032_7151261">评论,因为OP (2011),Go 1.16,2021 年第 1 季度 附带 弃用 io/ioutil

io/ioutil 软件包已转变是一个定义不明确且难以理解的事物的集合。
该包提供的所有功能已移至其他包。 io/ioutil 包仍然存在并将继续像以前一样工作,但我们鼓励新代码使用 io 操作系统包。

回到问题:

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

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

// 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 功能 也被冻结了

Ian Lance Taylor 解释

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

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

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

2024: as m0j0 mentioned in the comments that, since the OP (2011), Go 1.16, Q1 2021 came with the deprecation of io/ioutil

The io/ioutil package has turned out to be a poorly defined and hard to understand collection of things.
All functionality provided by the package has been moved to other packages. The io/ioutil package remains and will continue to work as before, but we encourage new code to use the new definitions in the io and os packages.

Back to the question:

But how can I append to a file? Is there a built in method?

There actually was a proposal to implement such a method!
See proposal 30159 and the code PR 30157, in Q1 2019:

// 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
}

It was rejected (and its associated issue 30207: proposal: cmd/go/internal/lockedfile: add Append function is also frozen.

Ian Lance Taylor explained:

If we add a function AppendFile, it must always work reliably as people expect, regardless of what else is happening in the system.
It really doesn't help to use advisory locking (flock).
There's nothing wrong with a program that uses advisory locking to handle this, but that can't be a function named AppendFile in the standard library.

So the other answers are fine in your own project, but not in the standard library, as Rob Pike mentioned:

It's all but impossible to implement this correctly in the face of concurrency, making it unwise to offer to people who might expect it to work under those conditions.
It needs operating-system-level semantics to work, and we don't have that.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文