Golang 从 net.TCPConn 读取字节

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

Golang Read Bytes from net.TCPConn

问题

ioutil.ReadAll函数没有直接提供一个能够在遇到EOF或读取到指定字节数(以先到者为准)时停止读取的版本。

但是,你可以使用io.LimitedReader结构体来实现类似的功能。io.LimitedReader接受一个io.Reader接口和一个字节数作为参数,并将读取操作限制在指定的字节数内。

下面是一个示例代码,演示如何使用io.LimitedReader来实现你所描述的功能:

package main

import (
	"fmt"
	"io"
	"io/ioutil"
	"strings"
)

func main() {
	reader := strings.NewReader("This is a sample string.")
	limit := 10 // 限制读取的字节数

	lr := &io.LimitedReader{R: reader, N: int64(limit)}
	data, err := ioutil.ReadAll(lr)
	if err != nil {
		fmt.Println("读取错误:", err)
		return
	}

	fmt.Println(string(data))
}

在上面的示例中,我们使用strings.NewReader创建了一个包含示例字符串的io.Reader接口。然后,我们创建了一个io.LimitedReader,将其作为参数传递给ioutil.ReadAll函数。io.LimitedReader将限制读取操作在指定的字节数内,即使还没有遇到EOF。

请注意,上述示例中的limit变量可以根据你的需求进行调整,以指定你想要读取的字节数。

英文:

Is there a version of ioutil.ReadAll that will read until it reaches an EOF OR if it reads n bytes (whichever comes first)?

I cannot just take the first n bytes from an ioutil.ReadAll dump for DOS reasons.

答案1

得分: 3

你可以使用io.ReadFullio.LimitedReader或者http.MaxBytesReader来实现你需要的功能。如果你需要不同的行为,可以先查看它们的实现方式,然后根据需要进行修改。

英文:

io.ReadFull
or
io.LimitedReader
or
http.MaxBytesReader.

If you need something different first look at how those are implemented, it'd be trivial to roll your own with tweaked behavior.

答案2

得分: 3

有几种方法可以实现您的要求,您可以选择其中一种。

func ReadFull

func ReadFull(r Reader, buf []byte) (n int, err error)

> ReadFull 从 r 中精确地读取 len(buf) 个字节到 buf 中。它返回复制的字节数和一个错误,如果读取的字节数少于 len(buf)。只有在没有读取任何字节时,错误才是 EOF。

func LimitReader

func LimitReader(r Reader, n int64) Reader

LimitReader 返回一个从 r 中读取,但在读取 n 个字节后停止并返回 EOF 的 Reader。底层实现是 *LimitedReader。

func CopyN

func CopyN(dst Writer, src Reader, n int64) (written int64, err error)

> CopyN 从 src 复制 n 个字节(或直到出现错误)到 dst。它返回复制的字节数和在复制过程中遇到的最早的错误。返回时,只有在 err == nil 时 written == n。

func ReadAtLeast

func ReadAtLeast(r Reader, buf []byte, min int) (n int, err error)

> ReadAtLeast 从 r 中读取到 buf 中,直到至少读取了 min 个字节。它返回复制的字节数和一个错误,如果读取的字节数少于 min。只有在没有读取任何字节时,错误才是 EOF。

英文:

There are a couple of ways to achieve your requirement. You can use either one.

func ReadFull

func ReadFull(r Reader, buf []byte) (n int, err error)

> ReadFull reads exactly len(buf) bytes from r into buf. It returns the
> number of bytes copied and an error if fewer bytes were read. The
> error is EOF only if no bytes were read.

func LimitReader

func LimitReader(r Reader, n int64) Reader

LimitReader returns a Reader that reads from r but stops with EOF after n bytes. The underlying implementation is a *LimitedReader.

func CopyN

func CopyN(dst Writer, src Reader, n int64) (written int64, err error)

> CopyN copies n bytes (or until an error) from src to dst. It returns
> the number of bytes copied and the earliest error encountered while
> copying. On return, written == n if and only if err == nil.

func ReadAtLeast

func ReadAtLeast(r Reader, buf []byte, min int) (n int, err error)

> ReadAtLeast reads from r into buf until it has read at least min
> bytes. It returns the number of bytes copied and an error if fewer
> bytes were read. The error is EOF only if no bytes were read.

答案3

得分: 2

有两个选项。如果n是你想要读取的字节数,r是连接。

选项1:

p := make([]byte, n)
_, err := io.ReadFull(r, p)

选项2:

p, err := io.ReadAll(&io.LimitedReader{R: r, N: n})

如果应用程序通常填充缓冲区,则第一种选项更高效。

如果你正在从HTTP请求体中读取数据,则使用http.MaxBytesReader

英文:

There are two options. If n is the number of bytes you want to read and r is the connection.

Option 1:

p := make([]byte, n)
_, err := io.ReadFull(r, p)

Option 2:

p, err := io.ReadAll(&io.LimitedReader{R: r, N: n})

The first option is more efficient if the application typically fills the buffer.

If you are reading from an HTTP request body, then use http.MaxBytesReader.

huangapple
  • 本文由 发表于 2015年3月24日 06:48:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/29221872.html
匿名

发表评论

匿名网友

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

确定