Answer the question
In order to leave comments, you need to log in
How to write stdout to buffer and read from it line by line?
Given:
a third-party SDK of some Go library that launches an external process. It has the ability to write stdout, obtained from the output of this process in the form of multiline text.
SetStdout(writer io.Writer)
I need to implement a functionality that will allow me to send messages to the broker of 20 lines that were written using that writer. And, thus, send messages to the broker until all the output is over (streaming).
As far as I understand, I need to implement the interface io.Writer
by writing to some kind of buffer, and in another function, in the goroutine, read from there line by line and, as the buffer of 20 lines is filled, send them to the broker.
I hope I explained it clearly enough.
Show me how to do this with a simple code example.
Answer the question
In order to leave comments, you need to log in
You understand everything correctly, the goroutine can not be used.
You can do something like this
package main
import (
"bufio"
"bytes"
"fmt"
"io"
"log"
"os/exec"
)
type Executor struct {
wr io.Writer
}
func (e *Executor) SetStdout(w io.Writer) {
e.wr = w
}
func (e *Executor) Exec() error {
cmd := exec.Command("ls", "/etc")
cmd.Stdout = e.wr
err := cmd.Run()
return err
}
type BufferedBrokerWriter struct {
buffer bytes.Buffer
scanner *bufio.Scanner
}
func NewBufferedBrokerWriter() *BufferedBrokerWriter {
bw := &BufferedBrokerWriter{}
bw.scanner = bufio.NewScanner(&bw.buffer)
return bw
}
func (bw *BufferedBrokerWriter) Write(p []byte) (int, error) {
return bw.buffer.Write(p)
}
func (bw *BufferedBrokerWriter) ReadLines(cnt uint) ([]string, error) {
lines := make([]string, 0, cnt)
linesCnt := uint(0)
for bw.scanner.Scan() {
line := bw.scanner.Text()
err := bw.scanner.Err()
if err != nil || line == `` {
return lines, err
}
lines = append(lines, line)
linesCnt++
if linesCnt >= cnt {
return lines, nil
}
}
return nil, io.EOF
}
func main() {
// подключаетесь к вашему брокеру сообщений,
bw := NewBufferedBrokerWriter()
e := &Executor{}
e.SetStdout(bw)
err := e.Exec()
if err != nil {
log.Fatal(err)
}
for {
lines, err := bw.ReadLines(2)
if err == io.EOF {
break
}
fmt.Printf("Lines:\n%+v\n\n", lines)
}
}
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question