简体   繁体   中英

Writing buffer to file doesn't return error, so why is file empty afterwords?

While learning Go I'm trying to read all standard input and write it to a file. I'm sorry if this is a vague question, but I've spent a lot of time going over this code and I can't for the life of me understand why it's writing nothing to the file provided. Can someone please shed some light on what's wrong here?

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

And then...

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

Open opens a file in read-only mode.
Refer to documentation: https://golang.org/pkg/os/#Open

Instead, use OpenFile .

Also, always check for errors whenever you code. It'll save you at least weeks of work-hours in your lifetime.

Here is a working code:

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

In your code you can silently fail because you aren't checking the error. It's likely a path issue. You can change your code slightly and let ioutil handle file creation so that paths aren't so much of an issue. Remember to always check the errs

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM