2017-09-07 43 views
0

我想编写一个函数,它读取文件中的行并发送到通道中进行进一步处理。我是新来的快去这里是我想出了以下主要是课本上的例子阅读器功能:如何在一个匿名函数中逐行扫描一个文件并将其传递给一个通道

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()功能我传递一个文件指针到阅读器功能,并尝试漏出通道如下:

func main() { 
    out := reader(*f) 
    for range out { 
     fmt.Println(<-out) 
    } 
} 

但是,我得不到任何comilation或运行时错误,但输出为空。如果我不把for循环放到goroutine中,我可以用reader()函数打印文件,而不会出现任何问题。

我还试图将reader()函数中的扫描器,通道或两者都传递给匿名函数。但它没有解决问题。任何人都可以解释为什么此代码不起作用,以及如何补救?

回答

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 
} 

然后,从范围子句打印值,内接收到的for循环不是一个第二值​​:

func main() { 
    out := reader(os.Args[1]) 
    for line := range out { 
     fmt.Println(line) 
    } 
} 
相关问题