Golang 2015 - 如何关闭打开它的函数之外的文件?

时间:2015-09-12 23:45:38

标签: go

我正在尝试读取文件中的行。我想轻松打开一个文件,并一次解析一行,并删除一些样板打开和关闭。我正在传回指向“扫描仪”的指针。这只是一种愚蠢的方法吗?由于拆分,扫描仪是否已读取内容?有更好的方法吗?欢迎任何有关最佳实践的见解。

    func main() {
            var path string
            if len(os.Args) > 1 {
                    err, scanner := fileScanner(path)
                    if err == nil {
                            // Go through file line by line.
                            for scanner.Scan() {
                                    fmt.Println(scanner.Text())
                                    // or do other stuff
                            }
                            // so how do I make sure to close the file?
                    }
            }
    }

    // Return a scanner for a file.
    func fileScanner(path string) *bufio.Scanner {
            file, err := os.Open(path)
            if err != nil {
                    return err
            }
            //defer file.Close()
            scanner := bufio.NewScanner(file)
            scanner.Split(bufio.ScanLines)
            return err, scanner
    }

1 个答案:

答案 0 :(得分:0)

我认为最简单的解决方案就是不要在fileScanner函数中打开文件。

如果您从主函数中提取这些操作非常重要,那么考虑创建一个既包含扫描程序又包含文件指针的新结构类型,然后您可以定义要打开的类型的方法,关闭并获取扫描仪。这些方面的东西:

type fileScanner struct {
    File    *os.File
    Scanner *bufio.Scanner
}

func NewFileScanner() *fileScanner {
    return &fileScanner{}
}

func (f *fileScanner) Open(path string) (err error) {
    f.File, err = os.Open(path)
    return err
}

func (f *fileScanner) Close() error {
    return f.File.Close()
}

func (f *fileScanner) GetScanner() *bufio.Scanner {
    if f.Scanner == nil {
        f.Scanner = bufio.NewScanner(f.File)
        f.Scanner.Split(bufio.ScanLines)
    }
    return f.Scanner
}

func main() {
    var path string
    if len(os.Args) > 1 {
        fscanner := NewFileScanner()
        err := fscanner.Open(path)
        if err == nil {
            defer fscanner.Close()
            scanner := fscanner.GetScanner()
            // Go through file line by line.
            for scanner.Scan() {
                fmt.Println(scanner.Text())
                // or do other stuff
            }

        }
    }
}

为此目的,这是相当多的工作。其他替代方法是从您的函数返回文件(尽管您应该处理恐慌以避免任何可能的泄漏)或返回清理函数。