从io.Reader的Read方法中获取流式传输的字节数。

huangapple go评论75阅读模式
英文:

Get the amount of bytes streamed from an io.Reader Read

问题

这是我的代码片段,它执行一个GET请求,并将响应流式传输到cmd.Stdin

resp, err := httpClient.Get(url)
if err != nil {
    err = errors.Wrap(err, "HTTP请求失败")
    return
}
reader := bufio.NewReader(resp.Body)

args = append(args, "-") // 在stdin上继续监听文件数据
cmd := exec.Command("exiftool", args...)

stdout, err := cmd.StdoutPipe()
if err != nil {
    return
}
cmd.Stdin = reader

err = cmd.Start()
if err != nil {
    return
}

我想知道在执行完成时流式传输了多少数据。

所以我需要捕获在流式传输时正在读取的内容,或者至少捕获正在读取的内容的大小。

英文:

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.

答案1

得分: 4

包装读取器。在包装器中计数。

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
}

将其插入到应用程序中,如下所示:

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) // 打印读取的字节数。

因为 exec 包在从响应复制到 stdin 时使用缓冲区所以 bufio.Reader 不太可能提供好处如果确实有一些好处可以使用以下**其中一种**选项

```go
reader := &wrapper{Reader: bufio.NewReader(resp.Body)}  // 选项 1

cmd.Stdin = bufio.NewReader(reader)                     // 选项 2
英文:

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

huangapple
  • 本文由 发表于 2022年9月30日 04:41:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/73901396.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定