我想编写一个函数,从文件中读取行,然后发送到通道进行进一步处理。我是Go的新手,这里是我提出的阅读器功能,主要是教科书示例:
func reader(file string) <-chan string {
out := make(chan string)
f, err := os.Open(file)
if err != nil {
log.Fatal(err)
}
defer f.Close()
s := bufio.NewScanner(f)
go func() {
for s.Scan() {
out <- s.Text()
}
close(out)
}()
return out
}
在main()
函数中,我将文件指针传递给reader函数,并尝试按如下方式排出out通道:
func main() {
out := reader(*f)
for range out {
fmt.Println(<-out)
}
}
我没有编译或运行时错误,但输出为空。如果我没有将for循环放入goroutine,我可以使用reader()
函数打印文件,无任何问题。
我还尝试将reader()
功能中的扫描仪,频道或两者传递到匿名功能。但它并没有解决问题。任何人都可以解释为什么这段代码不起作用以及如何解决它?
答案 0 :(得分:0)
您在阅读之前关闭了该文件。
你只是每隔一行打印一次。
将延迟移动到实际发生读取的闭包中。
func reader(file string) <-chan string {
out := make(chan string)
f, err := os.Open(file)
if err != nil {
log.Fatal(err)
}
s := bufio.NewScanner(f)
go func() {
defer f.Close()
defer close(out)
for s.Scan() {
out <- s.Text()
}
if err := s.Err(); err != nil {
fmt.Println("error reading file:", err)
}
}()
return out
}
然后打印range子句中的值,而不是for循环中收到的第二个值:
func main() {
out := reader(os.Args[1])
for line := range out {
fmt.Println(line)
}
}