我正在使用bufio.Scanner
和http.Request
以及go例程来并行计算单词和行的小脚本。
package main
import (
"bufio"
"fmt"
"io"
"log"
"net/http"
"time"
)
func main() {
err := request("http://www.google.com")
if err != nil {
log.Fatal(err)
}
// just keep main alive with sleep for now
time.Sleep(2 * time.Second)
}
func request(url string) error {
res, err := http.Get(url)
if err != nil {
return err
}
go scanLineWise(res.Body)
go scanWordWise(res.Body)
return err
}
func scanLineWise(r io.Reader) {
s := bufio.NewScanner(r)
s.Split(bufio.ScanLines)
i := 0
for s.Scan() {
i++
}
fmt.Printf("Counted %d lines.\n", i)
}
func scanWordWise(r io.Reader) {
s := bufio.NewScanner(r)
s.Split(bufio.ScanWords)
i := 0
for s.Scan() {
i++
}
fmt.Printf("Counted %d words.\n", i)
}
与流scanLineWise
或多或少地期望一样,scalWordWise
将计数一个数字。这是因为scanLineWise
已从req.Body
读取所有内容。
我想知道:如何优雅地解决这个问题?
我首先想到的是构建一个实现io.Reader
和io.Writer
的结构。我们可以使用io.Copy
来读取req.Body
并将其写入writer
。当扫描仪从该写入器读取数据时,写入器将复制数据而不是读取数据。不幸的是,随着时间的流逝,这只会收集内存并破坏整个流的想法。
我正在研究一个小的脚本,该脚本使用bufio.Scanner和http.Request以及go例程来并行计算单词和行数。包主要导入(“ bufio”“ fmt”“ io”“ log” ...
这些选项非常简单-您可以维护数据的“流”,也可以缓冲主体。
如果您确实确实需要阅读更多的内容,然后顺序阅读一次,则需要将其缓冲在某个地方。无法解决。
您可以使用通道,在scanLineWise
中进行实际读数,然后将行传递到scanWordWise
,以获取example: