我有一些代码从一个文件复制到一个TCP套接字(如FTP服务器),并希望能够中止这个副本,如果需要的话。如何停止io.CopyN
我只是使用io.CopyN(套接字,文件,大小),并不能看到一种方式来表示中止。有任何想法吗?
我有一些代码从一个文件复制到一个TCP套接字(如FTP服务器),并希望能够中止这个副本,如果需要的话。如何停止io.CopyN
我只是使用io.CopyN(套接字,文件,大小),并不能看到一种方式来表示中止。有任何想法吗?
CopyN
尽量复制N个字节。如果您希望复制少于N个字节,则首先不要使用CopyN。我可能会将原始代码改为类似(未经测试的代码):
func copyUpToN(dst Writer, src Reader, n int64, signal chan int) (written int64, err error) {
buf := make([]byte, 32*1024)
for written < n {
select {
default:
case <-signal:
return 0, fmt.Errorf("Aborted") // or whatever
}
l := len(buf)
if d := n - written; d < int64(l) {
l = int(d)
}
nr, er := src.Read(buf[0:l])
if nr > 0 {
nw, ew := dst.Write(buf[0:nr])
if nw > 0 {
written += int64(nw)
}
if ew != nil {
err = ew
break
}
if nr != nw {
err = io.ErrShortWrite
break
}
}
if er != nil {
err = er
break
}
}
return written, err
}
刚刚关闭输入文件怎么样?然后io.CopyN
将返回一个错误并中止。
这里是一个演示(如果不是在Linux上的变化/dev/zero
& /dev/null
您的操作系统相当于运行!)
package main
import (
"fmt"
"io"
"log"
"os"
"time"
)
func main() {
in, err := os.Open("/dev/zero")
if err != nil {
log.Fatal(err)
}
out, err := os.Create("/dev/null")
if err != nil {
log.Fatal(err)
}
go func() {
time.Sleep(time.Second)
in.Close()
}()
written, err := io.CopyN(out, in, 1E12)
fmt.Printf("%d bytes written with error %s\n", written, err)
}
在运行时会打印出类似这样
9756147712 bytes written with error read /dev/zero: bad file descriptor
希望copyN会做大块,不是一次全部。 – Lodle 2013-02-10 11:46:10
32 * 1024是上述代码中的(可调整)块大小。 – zzzz 2013-02-10 12:12:19