在Golang中同时读取文件

阅读部分不是并发的,但处理是并发的。我用这种方式来命名标题,因为我最有可能使用该短语再次搜索此问题。:)

尝试 超越示例 之后,我陷入僵局,因此这对我来说是一种学习经验。我的目标是:

  1. 逐行读取文件(最终使用缓冲区执行多行)。
  2. 将文本传递给func()执行某些正则表达式的工作。
  3. 将结果发送到某个地方,但要避免使用互斥或​​共享变量。我正在将整数(总是数字1)发送到通道。这有点愚蠢,但是如果不引起问题,除非您有更整洁的选择,否则我想像这样保留它。
  4. 使用工作池执行此操作。我不确定如何告诉工人重新排队?

这是游乐场的链接。我试图写出有用的评论,希望这很有道理。我的设计可能是完全错误的,所以请毫不犹豫地进行重构。

package main

import (

"bufio"

"fmt"

"regexp"

"strings"

"sync"

)

func telephoneNumbersInFile(path string) int {

file := strings.NewReader(path)

var telephone = regexp.MustCompile(`\(\d+\)\s\d+-\d+`)

// do I need buffered channels here?

jobs := make(chan string)

results := make(chan int)

// I think we need a wait group, not sure.

wg := new(sync.WaitGroup)

// start up some workers that will block and wait?

for w := 1; w <= 3; w++ {

wg.Add(1)

go matchTelephoneNumbers(jobs, results, wg, telephone)

}

// go over a file line by line and queue up a ton of work

scanner := bufio.NewScanner(file)

for scanner.Scan() {

// Later I want to create a buffer of lines, not just line-by-line here ...

jobs <- scanner.Text()

}

close(jobs)

wg.Wait()

// Add up the results from the results channel.

// The rest of this isn't even working so ignore for now.

counts := 0

// for v := range results {

// counts += v

// }

return counts

}

func matchTelephoneNumbers(jobs <-chan string, results chan<- int, wg *sync.WaitGroup, telephone *regexp.Regexp) {

// Decreasing internal counter for wait-group as soon as goroutine finishes

defer wg.Done()

// eventually I want to have a []string channel to work on a chunk of lines not just one line of text

for j := range jobs {

if telephone.MatchString(j) {

results <- 1

}

}

}

func main() {

// An artificial input source. Normally this is a file passed on the command line.

const input = "Foo\n(555) 123-3456\nBar\nBaz"

numberOfTelephoneNumbers := telephoneNumbersInFile(input)

fmt.Println(numberOfTelephoneNumbers)

}

回答:

您快要准备好了,只需要在goroutine的同步上做一些工作即可。您的问题是您试图在相同的例程中提供解析器并收集结果,但这无法完成。

我提出以下建议:

  1. 在单独的例程中运行扫描仪,读取所有内容后关闭输入通道。
  2. 运行单独的例程,等待解析器完成工作,然后关闭输出通道。
  3. 在主例程中收集所有结果。

相关更改如下所示:

// Go over a file line by line and queue up a ton of work

go func() {

scanner := bufio.NewScanner(file)

for scanner.Scan() {

jobs <- scanner.Text()

}

close(jobs)

}()

// Collect all the results...

// First, make sure we close the result channel when everything was processed

go func() {

wg.Wait()

close(results)

}()

// Now, add up the results from the results channel until closed

counts := 0

for v := range results {

counts += v

}

在操场上完全可用的示例:http :

//play.golang.org/p/coja1_w-fY

值得补充的是,您不一定需要WaitGroup实现相同的目标,您需要知道的是何时停止接收结果。例如,可以通过扫描仪广告(在频道上)读取多少行,然后收集器仅读取指定数量的结果(您也需要发送零)来实现。

以上是 在Golang中同时读取文件 的全部内容, 来源链接: utcz.com/qa/427659.html

回到顶部