Files
the-way-to-go_ZH_CN/eBook/12.8.md
2015-09-29 23:24:46 +08:00

107 lines
3.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 一个使用接口的实际例子:fmt.Fprintf
例子程序`io_interfaces.go`很好的阐述了io包中的接口概念。
示例 12.15 [io_interfaces.go](examples/chapter_12/io_interfaces.go)
```go
// interfaces being used in the GO-package fmt
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
// unbuffered
fmt.Fprintf(os.Stdout, "%s\n", "hello world! - unbuffered")
// buffered: os.Stdout implements io.Writer
buf := bufio.NewWriter(os.Stdout)
// and now so does buf.
fmt.Fprintf(buf, "%s\n", "hello world! - buffered")
buf.Flush()
}
```
输出:
```
hello world! - unbuffered
hello world! - buffered
```
下面是`fmt.Fprintf()`函数的实际签名
```go
func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error)
```
其不是写入一个文件,而是写入一个`io.Writer`接口类型的变量,下面是`Writer`接口在io包中的定义
```go
type Writer interface {
Write(p []byte) (n int, err error)
}
```
`fmt.Fprintf()`依据指定的格式向第一个参数内写入字符串,第一参数必须实现了`io.Writer`接口。`Fprintf()`能够写入任何类型,只要其实现了`Write`方法,包括`os.Stdout`,文件例如os.File,管道网络连接通道等等同样的也可以使用bufio包中缓冲写入。bufio包中定义了`type Writer struct{...}`
bufio.Writer实现了Write方法
```go
func (b *Writer) Write(p []byte) (nn int, err error)
```
它还有一个工厂函数:传给它一个`io.Writer`类型的参数,它会返回一个缓冲的`bufio.Writer`类型的`io.Writer`:
```go
func NewWriter(wr io.Writer) (b *Writer)
```
其适合任何形式的缓冲写入。
在缓冲写入的最后千万不要忘了使用`Flush()`,否则最后的输出不会被写入。
在15.2-15.8章节,我们将使用`fmt.Fprint`函数向`http.ResponseWriter`写入其同样实现了io.Writer接口。
**练习 12.7**[remove_3till5char.go](exercises/chapter_12/remove_3till5char.go)
下面的代码有一个输入文件`goprogram.go`然后以每一行为单位读取从读取的当前行中截取第3到第5的字节写入另一个文件。然而当你运行这个程序输出的文件却是个空文件。找出程序逻辑中的bug修正它并测试。
```go
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
inputFile, _ := os.Open("goprogram.go")
outputFile, _ := os.OpenFile("goprogramT.go", os.O_WRONLY|os.O_CREATE, 0666)
defer inputFile.Close()
defer outputFile.Close()
inputReader := bufio.NewReader(inputFile)
outputWriter := bufio.NewWriter(outputFile)
for {
inputString, _, readerError := inputReader.ReadLine()
if readerError == io.EOF {
fmt.Println("EOF")
return
}
outputString := string([]byte(inputString)[2:5]) + "\r\n"
n, err := outputWriter.WriteString(outputString)
if err != nil {
fmt.Println(err)
return
}
}
fmt.Println("Conversion done")
}
```
## 链接
- [目录](directory.md)
- 上一节:[用defer关闭文件](12.7.md)
- 下一节:[格式化Json数据](12.9.md)