2016-02-15 03:06:34 +00:00
|
|
|
|
### 5.4.2. 文件结尾错误(EOF)
|
2016-01-02 14:12:38 +00:00
|
|
|
|
|
2016-02-15 03:06:34 +00:00
|
|
|
|
函数经常会返回多种错误,这对终端用户来说可能会很有趣,但对程序而言,这使得情况变得复杂。很多时候,程序必须根据错误类型,作出不同的响应。让我们考虑这样一个例子:从文件中读取n个字节。如果n等于文件的长度,读取过程的任何错误都表示失败。如果n小于文件的长度,调用者会重复的读取固定大小的数据直到文件结束。这会导致调用者必须分别处理由文件结束引起的各种错误。基于这样的原因,io包保证任何由文件结束引起的读取失败都返回同一个错误——io.EOF,该错误在io包中定义:
|
2016-01-06 01:39:11 +00:00
|
|
|
|
|
|
|
|
|
```Go
|
2016-01-05 15:46:55 +00:00
|
|
|
|
package io
|
2016-01-06 01:39:11 +00:00
|
|
|
|
|
2016-01-05 15:46:55 +00:00
|
|
|
|
import "errors"
|
2016-01-06 01:39:11 +00:00
|
|
|
|
|
2016-01-05 15:46:55 +00:00
|
|
|
|
// EOF is the error returned by Read when no more input is available.
|
|
|
|
|
var EOF = errors.New("EOF")
|
|
|
|
|
```
|
2016-01-06 01:39:11 +00:00
|
|
|
|
|
2016-02-15 03:06:34 +00:00
|
|
|
|
调用者只需通过简单的比较,就可以检测出这个错误。下面的例子展示了如何从标准输入中读取字符,以及判断文件结束。(4.3的chartcount程序展示了更加复杂的代码)
|
2016-01-06 01:39:11 +00:00
|
|
|
|
|
|
|
|
|
```Go
|
2016-01-05 15:46:55 +00:00
|
|
|
|
in := bufio.NewReader(os.Stdin)
|
|
|
|
|
for {
|
|
|
|
|
r, _, err := in.ReadRune()
|
|
|
|
|
if err == io.EOF {
|
|
|
|
|
break // finished reading
|
|
|
|
|
}
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("read failed:%v", err)
|
|
|
|
|
}
|
2016-01-06 01:39:11 +00:00
|
|
|
|
// ...use r…
|
2016-01-05 15:46:55 +00:00
|
|
|
|
}
|
|
|
|
|
```
|
2016-01-06 01:39:11 +00:00
|
|
|
|
|
2016-02-15 03:06:34 +00:00
|
|
|
|
因为文件结束这种错误不需要更多的描述,所以io.EOF有固定的错误信息——“EOF”。对于其他错误,我们可能需要在错误信息中描述错误的类型和数量,这使得我们不能像io.EOF一样采用固定的错误信息。在7.11节中,我们会提出更系统的方法区分某些固定的错误值。
|