【问题标题】:Writing buffer to file doesn't return error, so why is file empty afterwords?将缓冲区写入文件不会返回错误,那么为什么文件后记为空?
【发布时间】:2017-07-23 21:23:03
【问题描述】:

我正在尝试读取所有标准输入并将其写入文件。它没有向提供的文件写入任何内容。为什么它不起作用?

package main

import (
    "os"
    "bytes"
    "fmt"
    "bufio"
)

func main() {
    fn := os.Args[1]
    var input bytes.Buffer
    scanner := bufio.NewScanner(os.Stdin)

    for scanner.Scan() {
        fmt.Fprintf(&input, scanner.Text())
        fmt.Fprintf(&input, "\n")
    }   

    fi, _ := os.Open(fn)
    defer fi.Close()

    fi.Write(input.Bytes())
}

然后……

touch writetothis.txt
echo "input text" | go run main.go writetothis.txt
# writetothis.txt is empty

【问题讨论】:

  • 你没有检查fi, _ := os.Open(fn)线上的错误你怎么知道它甚至打开了..它可能会默默地失败。

标签: go buffer


【解决方案1】:

Open 以只读模式打开文件。
参考文档:https://golang.org/pkg/os/#Open

改为使用OpenFile

此外,每次编码时都要检查错误。它可以为您节省至少数周的工作时间。

这是一个工作代码:

package main

import (
    "bufio"
    "bytes"
    "fmt"
    "os"
)

func main() {
    fn := os.Args[1]
    var input bytes.Buffer
    scanner := bufio.NewScanner(os.Stdin)

    for scanner.Scan() {
        fmt.Fprintf(&input, scanner.Text())
        fmt.Fprintf(&input, "\n")
    }

    fmt.Println(input.Bytes())
    fi, err := os.OpenFile(fn, os.O_RDWR|os.O_CREATE, 0755)

    if err != nil {
        fmt.Println("Error with Open()",err)
    }
    defer fi.Close()

    n, err := fi.Write(input.Bytes())
    if err != nil {
        fmt.Println("Error with Write()", err)
    }
    fmt.Println("Bytes written to file: ",n)
}

【讨论】:

  • os.Create 如果文件只是被写入并且内容已经存在则应该丢弃它会更简单。如果它正在被读写,或者如果它需要打开以进行附加,那么os.OpenFile绝对是要走的路。
【解决方案2】:

在您的代码中,您可以静默失败,因为您没有检查错误。应该是路径问题。您可以稍微更改您的代码并让ioutil 处理文件创建,这样路径就不是什么大问题了。记得经常检查错误

package main

import (
    "bufio"
    "bytes"
    "fmt"
    "io/ioutil"
    "log"
    "os"
)

func main() {
    fn := os.Args[1]
    var input bytes.Buffer
    scanner := bufio.NewScanner(os.Stdin)

    for scanner.Scan() {
        fmt.Fprintf(&input, scanner.Text())
        fmt.Fprintf(&input, "\n")
    }

    err := ioutil.WriteFile(fn, input.Bytes(), 0644)
    if err != nil {
        log.Fatal(err)
    }
}

【讨论】:

  • 您应该检查错误是正确的,但在这种情况下,错误只是问题的症状。也就是说,OP 可能还没有看到 ioutil.WriteFile,所以 +1 来说明 os.Create/os.OpenFile 的替代方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-11-26
  • 2020-03-02
  • 1970-01-01
  • 2015-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多