在Golang中连续运行io.Copy(os.Stdout,&r)时得到不同的结果

时间:2018-11-19 00:18:58

标签: go

我正在玩Golang。关于io.Copy 我在代码中放置了2个连续的io.Copy,但是我希望它输出两次result(testtesttest)。但是第二个是零。谁能帮忙解释原因? tks

package main

import (
    "io"
    "os"
    "strings"
    "fmt"

)

type testReader struct {
    w io.Reader
    str string

}


func (tt *testReader) Read (b []byte) (n int, err error) {


    io.Copy(os.Stdout, tt.w)
     n, err = tt.w.Read(b)
     if tt.w !=nil {
        return 0,io.EOF
      }
    return
}

func main() {
    s := strings.NewReader("testtesttest!!!")
    r := testReader{s,"ttthhh"}
    fmt.Println(&r)
    io.Copy(os.Stdout, &r)
//  s.Seek(0,0)   // solution from Poy's answer
    io.Copy(os.Stdout, &r)

}

2 个答案:

答案 0 :(得分:4)

我将把给定的例子简化为(因为有一些噪音):

package main

import (
    "io"
    "os"
    "strings"
)

func main() {
    s := strings.NewReader("testtesttest")
    io.Copy(os.Stdout, s) // Will print "testtesttest"
    io.Copy(os.Stdout, s) // Won't print anything
}

第二个副本不输出任何内容的原因是io.Readers)已被读取。从io.Reader读取不是幂等的(不能两次调用以获得相同的结果)。 它也没有办法“重置”它或其他任何东西。

正如@JRLambert指出的那样,您有s.Seek()s.Reset()可以让您重新开始阅读。

答案 1 :(得分:0)

快速添加到目前为止提供的所有正确答案(@poy和@JRLambert)...如果您想多次使用\App\Article:all(); ,请使用io.TeeReaderio.MultiWriter一旦。以下是some examples of using each


使用io.Copy

io.TeeReader


使用package main import ( "bytes" "crypto/md5" "encoding/hex" "fmt" "io" "io/ioutil" "os" ) func main() { sourceFile, _ := os.Open("source/ebook.pdf") var buf bytes.Buffer tee := io.TeeReader(sourceFile, &buf) process := func(sourceReader io.Reader) { targetFile, _ := os.Create("target/ebook.pdf") defer targetFile.Close() if _, err := io.Copy(targetFile, sourceReader); err != nil { fmt.Println(err) } } process(tee) fmt.Println(checksum(&buf)) } func checksum(buf *bytes.Buffer) string { h := md5.New() b, _ := ioutil.ReadAll(buf) if _, err := h.Write(b); err != nil { fmt.Println(err) } return hex.EncodeToString(h.Sum(nil)[:16]) }

io.MultiWriter