您的位置 首页 golang

Golang中读取文件最常见的错误

使用文件名作为输入

另一个常见错误是将文件名传递给函数。

假设我们必须实现一个函数来计算文件中的空行数。最自然的实现是这样的:

filename 作为输入给出,所以我们打开它然后我们实现我们的逻辑,对吧?

func count( file name string) (int, error) {
 file, err := os. Open (filename)
 if err !=  nil  {
 return 0, errors.Wrapf(err, "unable to open %s", filename)
 }
 defer file. Close ()
 scanner := buf io .NewScanner(file)
 count := 0
 for scanner.Scan() {
 if scanner.Text() == "" {
 count++
 }
 }
 return count, nil
}
 

现在,假设我们希望在此函数之上实现 单元测试 ,以使用普通文件,空文件,具有不同编码类型的文件等进行测试。很容易变得非常难以管理。

此外,如果我们想要实现相同的逻辑但是对于HTTP主体,例如,我们将不得不为此创建另一个函数。

Go有两个很棒的抽象:io. reader 和io.Writer。相反,通过一个文件名,我们可以简单地传递一个io.Reader作为 抽象 的数据源。

它是文件吗?一个HTTP正文?字节缓冲区?这并不重要,因为我们仍然会使用相同的Read方法。

在我们的例子中,我们甚至可以缓冲输入以逐行读取它。所以,我们可以使用bufio.Reader它的ReadLine方法:

func count(reader *bufio.Reader) (int, error) {
 count := 0
 for {
 line, _, err := reader.ReadLine()
 if err != nil {
 switch err {
 default:
 return 0, errors.Wrapf(err, "unable to read")
 case io. EOF :
 return count, nil
 }
 }
 if len(line) == 0 {
 count++
 }
 }
}
 

现在,打开文件本身的责任委托给count客户:

func ReadFile() {
 filename := os.Getenv("fileExample")
 file, err := os.Open(filename)
 if err != nil {
 return errors.Wrapf(err, "unable to open %s", filename)
 }
 defer file.Close()
 count, err := count(bufio.NewReader(file))
}
 

使用第二种实现,无论 实际数据源 如何,都可以调用该函数。同时,它将 促进 我们的单元测试,因为我们可以简单地创建一个bufio.Reader来自string:

count, err := count(bufio.NewReader(strings.NewReader("input")))
 

翻译自:

文章来源:智云一二三科技

文章标题:Golang中读取文件最常见的错误

文章地址:https://www.zhihuclub.com/90371.shtml

关于作者: 智云科技

热门文章

网站地图