将缓冲区写入文件时没有返回错误,那么为什么文件之后是空的?

huangapple go评论165阅读模式
英文:

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

问题

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

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 是空的

问题可能出在文件写入部分。你可以尝试在写入文件之前调用fi.Sync()来确保缓冲区中的数据被刷新到磁盘。修改后的代码如下:

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.OpenFile(fn, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
    defer fi.Close()

    fi.Write(input.Bytes())
    fi.Sync()
}

这样应该能够正确地将输入写入文件。

英文:

I'm trying to read all standard input and write it to a file. It's writing nothing to the file provided. Why is it not working?

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

答案1

得分: 6

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)
}
英文:

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

答案2

得分: 1

在你的代码中,你没有检查错误,所以可能会出现静默失败。这很可能是一个路径问题。你可以稍微修改代码,让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)
	}
}

希望对你有帮助!

英文:

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

huangapple
  • 本文由 发表于 2017年7月24日 05:23:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/45270023.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定