3

ファイルから tcp ソケット (ftp サーバーなど) にコピーするコードがあり、必要に応じてこのコピーを中止できるようにしたいと考えています。

io.CopyN(socket, file, size) を使用しているだけで、中止を通知する方法がわかりません。何か案は?

4

2 に答える 2

6

入力ファイルを閉じるだけではどうですか? io.CopyNその後、エラーを返して中止します。

これがデモンストレーションです(Linuxで実行されていない場合は、お使いのOSと同等のものに変更してください!/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
于 2013-02-10T10:49:14.567 に答える
4

CopyNN バイトをコピーしようとします。オプションで 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
}
于 2013-02-10T09:40:44.530 に答える