[Golang] Caveat of fmt.Fprintf Use
Do not use fmt.Fprintf to write to file.
The following code writes string to file via fmt.Fprintf:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | package write import ( "fmt" "os" ) func BadWriteStringToFile(filepath, s string) error { fo, err := os.Create(filepath) if err != nil { return err } defer fo.Close() _, err = fmt.Fprintf(fo, s) if err != nil { return err } return nil } |
The above code is ok if there is no % in the string. What if % in the string?
if err := BadWriteStringToFile("bad.txt", "% in string\n"); err != nil {
panic(err)
}
The output (bad.txt) is:
%!i(MISSING)n string
This is not the result we want, so what is the good way to write string to file? The answer is use io.Copy:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | package write import ( "io" "os" "strings" ) func WriteStringToFile(filepath, s string) error { fo, err := os.Create(filepath) if err != nil { return err } defer fo.Close() _, err = io.Copy(fo, strings.NewReader(s)) if err != nil { return err } return nil } |
Again write the same string to file:
if err := WriteStringToFile("good.txt", "% in string\n"); err != nil {
panic(err)
}
The output (good.txt):
% in string
This is the result we want!
Tested on: Ubuntu Linux 16.10, Go 1.8.
References:
[1] | os - The Go Programming Language |
[2] | io - The Go Programming Language |
[3] | fmt - The Go Programming Language |