エラーがわかりません。これは、マシン「A」で実行するmain.goです。
package main
import (
"fmt"
"net"
"os"
"github.com/mistifyio/go-zfs"
)
func main() {
// Listen for incoming connections.
l, err := net.Listen("tcp", "192.168.99.5:9977")
if err != nil ...
// Close the listener when the application closes.
defer l.Close()
fmt.Println("Listening on " + CONN_Host + ":" + CONN_PORT)
for {
// Listen for an incoming connection.
conn, err := l.Accept()
if err != nil ...
//Handle connections in a new goroutine.
go handleRequest(conn)
}
}
// Handles incoming requests.
func handleRequest(conn net.Conn) {
// Make a buffer to hold incoming data.
buff := make([]byte, 1024)
// Read the incoming connection into the buffer.
_, err := conn.Read(buff)
if err != nil {
fmt.Printf("Error reading: %s.\n", err.Error())
}
// ReceiveSnapshot
ds, err := zfs.ReceiveSnapshot(buff, "tank/replication")
if err != nil {
fmt.Printf("Error receiving: %s.\n", err.Error())
}
fmt.Printf("%s... done!\n", ds)
// Send a response back to person contacting us.
conn.Write([]byte("Received!"))
// Close the connection when you're done with it.
conn.Close()
}
ここで、github.com/mistifyio/go-zfs /zfs.goの関数ReceiveSnapshotを紹介します。
type command struct {
Command string
Stdin io.Reader
Stdout io.Writer
}
func ReceiveSnapshot(input io.Reader, name string) (*Dataset, error) {
c := command{Command: "zfs", Stdin: input}
_, err := c.Run("receive", name)
if err != nil {
return nil, err
}
return GetDataset(name)
}
私はgolangpkgでio.Readerのドキュメントを見ました:
type Reader interface {
Read(p []byte) (n int, err error)
}
エラーが発生するのはなぜですか...
...私がgo install
を作るとき?
リーダーのReader
メソッドが_[]byte
_をパラメーターとして受け取るという理由だけで、_[]byte
_がRead
と同等であると考える場合、ロジックのステップが欠落していると思います。 。
明確にしようと思います:
ReceiveSnapshot
関数は、パラメーターとしてReader
を想定しています。
_ReceiveSnapshot( input io.Reader ...
_
型がReader
インターフェースを満たすためには、その型自体がこの関数を実装する必要があります。
_Read(p []byte) (n int, err error)
_
型はReader
になるためにその関数をimplementする必要があることに注意してください。
_[]byte
_はRead
関数を実装していません。 Read
への引数がたまたま_[]byte
_であるのは偶然です。
これを機能させるには、ReceiveSnapshot
に適切なReader
を送信する必要があります。
幸いなことに、_[]byte
_があり、それを読みたいというのは一般的な状況であるため、APIはこれを行う簡単な方法を提供します。
https://golang.org/pkg/bytes/#NewReader
ReceiveSnapshot
だけでなく、bytes.NewReader(buff)
をbuff
関数に送信する必要があります。
短い答え: _bytes.NewReader
_ を使用して、バッファを Reader タイプでラップします
または、 _bytes.NewBuffer
_ を使用して同様の効果を得ることができます。
ソースが文字列の場合は、 _strings.NewReader
_ を使用できます。
読者のリストはどんどん増えています: https://golang.org/search?q=Read#Global
より深い質問は次のとおりです:配列が_io.Reader
_インターフェイスを直接サポートしないのはなぜですか?
_io.Reader
_は、合計サイズが必ずしも事前にわかっているとは限らない一般的なデータストリームから読み取るという概念をサポートします。これをサポートするために、すべての入力データが使い果たされるまでRead
が繰り返し呼び出されます。多くの言語では、同様の読み取り関数を少なくとも2回呼び出す必要があります。最後の呼び出しでは、ファイルの終わりを示すフラグが返されます。
2つの値(そのうちの1つはタイプ error
)を返すことにより、Goは配列の読み取りをワンショットで完了することを可能にします。宛先バッファーは、使用可能なすべてのデータを消費するのに十分な大きさです-これは常に事前にわかっているわけではありません。
_io.Reader
_ インターフェースは、Read()
関数の署名と動作を指定します。
_func (T) Read(b []byte) (n int, err error)
_
読み取りは、指定されたバイトスライスにデータを入力し、入力されたバイト数とエラー値を返します。ストリームが終了すると、io.EOFエラーが返されます。
したがって、_io.Reader
_インターフェイスの動作方法により、単純なバイトバッファでは実装できません。後続のRead()
の呼び出し間の状態を記憶するには、ラッパー構造が必要です。
興味を引くために、これを実装する方法を示す例を次に示します...
_type MyReader struct {
src []byte
pos int
}
func (r *MyReader) Read(dst []byte) (n int, err error) {
n = copy(dst, r.src[r.pos:])
r.pos += n
if r.pos == len(r.src) {
return n, io.EOF
}
return
}
func NewMyReader(b []byte) *MyReader { return &MyReader{b, 0} }
_
また、Read()
の_[]byte
_パラメーターはソースではなく宛先バッファーであることに注意してください。