38

私はbufioパッケージのgolangの特定の関数を知っています。

func (b *Reader) Peek(n int) ([]byte, error)

Peekは、リーダーを進めずに次のnバイトを返します。バイトは、次の読み取り呼び出しで有効でなくなります。Peekが返すバイト数がn未満の場合は、読み取りが短い理由を説明するエラーも返します。nがbのバッファサイズより大きい場合、エラーはErrBufferFullです。

リーダーを進めるリーダーから特定のバイト数を読み取れるようにする必要があります。基本的には上記の機能と同じですが、読者を進化させます。誰かがこれを達成する方法を知っていますか?

4

7 に答える 7

85

このbufio.Readメソッドは、原資産を最大で1回呼び出すことに注意してください。つまり、 EOFに到達せずにio.Readを返すことができます。正確にバイトn < len(p)を読み取りたい場合、またはエラーで失敗したい場合は、次のように使用できます。len(p)io.ReadFull

n, err := io.ReadFull(reader, p)

これは、リーダーがバッファリングされている場合でも機能します。

于 2013-10-28T23:25:22.970 に答える
17
func (b *Reader) Read(p []byte) (n int, err error)

http://golang.org/pkg/bufio/#Reader.Read

読み取られるバイト数はに制限されますlen(p)

于 2012-12-01T16:44:47.717 に答える
6

TLDR:

my42bytes, err := ioutil.ReadAll(io.LimitReader(myReader, 42))

完全な答え:

@monicutaはio.ReadFull、どちらがうまく機能するかについて言及しました。ここで別の方法を提供します。それは連鎖ioutil.ReadAllしてio.LimitReader一緒に機能します。最初にドキュメントを読みましょう:

$ go doc ioutil.ReadAll
func ReadAll(r io.Reader) ([]byte, error)
     ReadAll reads from r until an error or EOF and returns the data it read. A
     successful call returns err == nil, not err == EOF. Because ReadAll is
     defined to read from src until EOF, it does not treat an EOF from Read as an
     error to be reported. 

$ go doc io.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.

したがって、から42バイトを取得するmyReader場合は、これを実行します

import (
        "io"
        "io/ioutil"
)

func main() {
        // myReader := ...
        my42bytes, err := ioutil.ReadAll(io.LimitReader(myReader, 42))
        if err != nil {
                panic(err)
        }
        //...
}

これはと同等のコードですio.ReadFull

$ go doc io.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. If an EOF happens after reading some but not all the
    bytes, ReadFull returns ErrUnexpectedEOF. On return, n == len(buf) if and
    only if err == nil. If r returns an error having read at least len(buf)
    bytes, the error is dropped.
import (
        "io"
)

func main() {
        // myReader := ...
        buf := make([]byte, 42)
        _, err := io.ReadFull(myReader, buf)
        if err != nil {
                panic(err)
        }
        //...
}

と比較するとio.ReadFull、手動でを作成する必要がないという利点がありますbuf。ここで、len(buf)は読み取りたいバイト数であり、読み取りbuf時に引数として渡す必要があります。

代わりに、io.LimitReaderから最大42バイトが必要であることを伝え、それらすべてを読み取るためmyReaderに呼び出しioutil.ReadAllて、結果をバイトのスライスとして返します。成功した場合、返されるスライスの長さは42であることが保証されます。

于 2019-05-15T03:45:16.767 に答える
3

私はRead()を好みます。特に、あらゆる種類のファイルを読み取る場合は、Read()を使用します。これは、データをチャンクで送信する場合にも役立ちます。以下に、その使用方法を示す例を示します。

fs, err := os.Open("fileName"); 

if err != nil{
    fmt.Println("error reading file")
    return
}

defer fs.Close()

reader := bufio.NewReader(fs)

buf := make([]byte, 1024)

for{
    v, _ := reader.Read(buf) //ReadString and ReadLine() also applicable or alternative

    if v == 0{
        return
    }
    //in case it is a string file, you could check its content here...
    fmt.Print(string(buf))
}
于 2013-12-02T18:12:32.757 に答える
2

nバイトサイズのバッファをリーダーに渡します。

于 2012-12-01T16:24:24.357 に答える
0

からバイトを読み取りたい場合はio.Readerio.Writer次を使用できます。io.CopyN

CopyNは、nバイト(またはエラーが発生するまで)をsrcからdstにコピーします。コピーされたバイト数と、コピー中に発生した最も早いエラーを返します。

戻り時に、err == nilの場合に限り、==nと記述します。

written, err := io.CopyN(dst, src, n)
if err != nil {
    // We didn't read the desired number of bytes
} else {
   // We can proceed successfully
}
于 2022-01-17T22:47:19.380 に答える
-1

これを行うには、バイトスライスを作成し、このスライスにデータを読み込む必要があります。

n := 512
buff := make([]byte, n)
fs.Read(buff)  // fs is your reader. Can be like this fs, _ := os.Open('file')

func (b *Reader) Read(p []byte) (n int, err error)

読み取りはデータをpに読み取ります。pに読み込まれたバイト数を返します。バイトは、基盤となるリーダーの最大1つの読み取りから取得されるため、nはlen(p)よりも小さい可能性があります。

于 2016-07-04T06:12:51.063 に答える