bufioパッケージのgolangの特定の関数を知っています。
func (b *Reader) Peek(n int) ([]byte, error)
Peekは次のnバイトを返しますリーダーを進めずに。バイトは、次の読み取り呼び出しで有効でなくなります。 Peekがnバイト未満を返す場合、読み取りが短い理由を説明するエラーも返します。 nがbのバッファサイズより大きい場合、エラーはErrBufferFullです。
リーダーを進めるであるリーダーから特定のバイト数を読み取ることができる必要があります。基本的に、上記の機能と同じですが、それは読者を進歩させます。誰かがこれを達成する方法を知っていますか?
_bufio.Read
_メソッドは、基になる_io.Read
_を最大で1回呼び出すことに注意してください。つまり、EOFに到達せずにn < len(p)
を返すことができます。正確にlen(p)
バイトを読み取るか、エラーで失敗する場合は、次のように_io.ReadFull
_を使用できます。
_n, err := io.ReadFull(reader, p)
_
これは、リーダーがバッファリングされている場合でも機能します。
_func (b *Reader) Read(p []byte) (n int, err error)
_
http://golang.org/pkg/bufio/#Reader.Read
読み込まれるバイト数はlen(p)
に制限されます
私は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))
}
Nバイトサイズのバッファをリーダーに渡します。
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.
_
したがって、myReader
から42バイトを取得する場合は、次のようにします。
_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
_にmyReader
から最大42バイトが必要であることを伝え、_ioutil.ReadAll
_を呼び出してすべてを読み取り、バイトのスライスとして結果を返します。成功した場合、返されるスライスは長さが42であることが保証されています。
これを行うには、バイトスライスを作成し、 read でこのスライスにデータを作成する必要があります。
_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)
Readはデータをpに読み込みます。 pに読み込まれたバイト数を返します。バイトは、基になるリーダーの最大1つの読み取りから取得されるため、nはlen(p)よりも小さい場合があります。