Here is a snippet of my code that does a GET request, and streams the response into cmd.Stdin
.
resp, err = httpClient.Get(url)
if err != nil {
err = errors.Wrap(err, "HTTP request failed")
return
}
reader = bufio.NewReader(resp.Body)
args = append(args, "-") // Keep listening on stdin for file data
cmd := exec.Command("exiftool", args...)
stdout, err := cmd.StdoutPipe()
if err != nil {
return
}
cmd.Stdin = reader
err = cmd.Start()
if err != nil {
return
}
I want to know how much data is streamed by the time it finishes executing.
So what I need is to capture what is being read while it's streaming, or at least capture the size of what is being read.
CodePudding user response:
Wrap the reader. Count in the wrapper.
type wrapper struct {
io.Reader
n int
}
func (w *wrapper) Read(p []byte) (int, error) {
n, err := w.Reader.Read(p)
w.n = n
return n, err
}
Plug it into your application like this:
args = append(args, "-")
cmd := exec.Command("exiftool", args...)
stdout, err := cmd.StdoutPipe()
if err != nil {
return
}
reader := &wrapper{Reader: resp.Body}
cmd.Stdin = reader
err = cmd.Run()
if err != nil {
return
}
fmt.Println(reader.n) // prints number of bytes read.
Because the exec package uses a buffer when copying from the response to the stdin, a bufio.Reader is unlikely to provide a benefit. In case there is some benefit, use one of these options;
reader := &wrapper{Reader: bufio.NewReader(resp.Body)} // Option 1
cmd.Stdin = bufio.NewReader(reader) // Option 2