Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/svn/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go 使用多个扫描仪时scanner.Scan()的顺序出现问题_Go_Buffer - Fatal编程技术网

Go 使用多个扫描仪时scanner.Scan()的顺序出现问题

Go 使用多个扫描仪时scanner.Scan()的顺序出现问题,go,buffer,Go,Buffer,对于某些背景来说,我是一个新手,但是在工作中编写这个程序的人离开了,所以代码现在是我的责任。此程序包装了一个CLI工具,该工具可写入stdout和stderr。我们希望在处理输出的同时,优雅地处理底层工具的错误 这是当前正在使用的相关代码片段: cmd := exec.Command(args[0], args[1:]...) stdout, err := cmd.StdoutPipe() if err != nil { log.Fatal(err) } stderr, er

对于某些背景来说,我是一个新手,但是在工作中编写这个程序的人离开了,所以代码现在是我的责任。此程序包装了一个CLI工具,该工具可写入stdout和stderr。我们希望在处理输出的同时,优雅地处理底层工具的错误

这是当前正在使用的相关代码片段:

cmd := exec.Command(args[0], args[1:]...)

stdout, err := cmd.StdoutPipe()
if err != nil {
        log.Fatal(err)
}

stderr, err := cmd.StderrPipe()
if err != nil {
        log.Fatal(err)
}

cmd.Start()

scanner := bufio.NewScanner(stdout)
errScanner := bufio.NewScanner(stderr)

for errScanner.Scan() {
        err := errScanner.Text()
        log.Fatal(err)
}

for scanner.Scan() {
        // proccess stdout data
}

if scanner.Err() != nil {
        log.Fatal(scanner.Err())
}

cmd.Wait()
通常情况下,这很好。但是,如果写入标准输出的数据大小超过了64 KB的buf.MaxScanTokenSize,则程序将挂起,没有错误。底层命令完成,但两个循环的扫描器都未命中。我发现如果我交换errScanner.Scan()和scanner.Scan()的位置,那么问题就不再发生。这就是我的意思:

cmd := exec.Command(args[0], args[1:]...)

stdout, err := cmd.StdoutPipe()
if err != nil {
        log.Fatal(err)
}

stderr, err := cmd.StderrPipe()
if err != nil {
        log.Fatal(err)
}

cmd.Start()

scanner := bufio.NewScanner(stdout)
errScanner := bufio.NewScanner(stderr)

for scanner.Scan() {
        // proccess stdout
}

for errScanner.Scan() {
        err := errScanner.Text()
        log.Fatal(err)
}

if scanner.Err() != nil {
        log.Fatal(scanner.Err())
}

cmd.Wait()
有人知道为什么会出现最初的问题,以及为什么更换两个扫描仪可以解决这个问题吗?我的猜测是,两个扫描仪共享相同的底层缓冲区,这可能会导致一些问题,但我创建了两个不同的缓冲区,并将它们分配给扫描仪,但这并没有解决问题


感谢您的帮助

按照编写方式,您的程序将等待从其中一个流中读取所有数据,具体取决于顺序。如果在从该流读取时,第二个流缓冲区填满,则正在运行的程序(您正在读取其输出的程序)将阻塞,因为它无法向该流写入更多输出

看起来您并没有真正处理错误,因此您可以在goroutine中读取错误流:

go () {
  for errScanner.Scan() {
     ...
  }
}()

for scanner.Scan() {
  ...
}


好的,这是有道理的,并且澄清了我的很多问题。谢谢