我正在尝试读取文件中的行。我想轻松打开一个文件,并一次解析一行,并删除一些样板打开和关闭。我正在传回指向“扫描仪”的指针。这只是一种愚蠢的方法吗?由于拆分,扫描仪是否已读取内容?有更好的方法吗?欢迎任何有关最佳实践的见解。
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
}
答案 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
}
}
}
}
为此目的,这是相当多的工作。其他替代方法是从您的函数返回文件(尽管您应该处理恐慌以避免任何可能的泄漏)或返回清理函数。