我试图将标准输出从mongodump流式传输到s3。我已经获得了S3任意长度流的语法,但我不明白如何将这两个函数联系起来。在开始上传到S3之前,我不想处理整个mongodump命令。这就是我到目前为止所做的:
values
不幸的是dumpCmd.Stdout是一个作家,而不是读者,我不知道如何将作者的输出传递给读者。
使用管道后,我现在收到一个新错误,可能属于一个新问题:
dumpCmd := exec.Command("mongodump", "--host", "<host>", "--port", "<port>", "--archive")
dumpCmd.Stdout = os.Stdout
uploader := s3manager.NewUploader(session.New(&aws.Config{Region: aws.String("us-east-1")}))
result, err := uploader.Upload(&s3manager.UploadInput{
Body: dumpCmd.Stdout,
Bucket: aws.String("myBucket"),
Key: aws.String("myKey"),
})
if err != nil {
log.Fatalln("Failed to upload", err)
}
log.Println("Successfully uploaded to", result.Location)
错误:
dumpCmd := exec.Command("mongodump", "--host", "<host>", "--port", "<port>", "--archive")
body, err := dumpCmd.StdoutPipe()
if err != nil {
// handle error
}
if err := dumpCmd.Start(); err != nil {
// handle error
}
uploader := s3manager.NewUploader(session.New(&aws.Config{Region: aws.String("us-east-1")}))
result, err := uploader.Upload(&s3manager.UploadInput{
Body: body,
Bucket: aws.String("myBucket"),
Key: aws.String("myKey"),
})
if err != nil {
log.Fatalln("Failed to upload", err)
}
if err := dumpCmd.Wait(); err != nil {
// handle error
}
log.Println("Successfully uploaded to", result.Location)
答案 0 :(得分:3)
使用pipe将命令输出连接到上传输入。
这里棘手的问题是上传者seeks on the body,但管道不支持搜索。为了避免这种情况,在管道周围创建一个包装器,以隐藏上传器中的Seek方法。
dumpCmd := exec.Command("mongodump", "--host", "<host>", "--port", "<port>", "--archive")
body, err := dumpCmd.StdoutPipe()
if err != nil {
// handle error
}
if err := dumpCmd.Start(); err != nil {
// handle error
}
// Wrap the pipe to hide the seek methods from the uploader
bodyWrap := struct {
io.Reader
}{body}
uploader := s3manager.NewUploader(session.New(&aws.Config{Region: aws.String("us-east-1")}))
result, err := uploader.Upload(&s3manager.UploadInput{
Body: bodyWrap,
Bucket: aws.String("net-openwhere-mongodb-snapshots-dev"),
Key: aws.String("myKey"),
})
if err != nil {
log.Fatalln("Failed to upload", err)
}
if err := dumpCmd.Wait(); err != nil {
// handle error
}
log.Println("Successfully uploaded to", result.Location)
答案 1 :(得分:-1)
您可以使用io.Copy
方法(godoc),其定义如下:
func Copy
func Copy(dst Writer,src Reader)(写入int64,错误错误)
将副本从src复制到dst,直到在src或a上达到EOF 发生错误。它返回复制的字节数和第一个 复制时遇到错误,如果有的话。
成功的复制返回err == nil,而不是err == EOF。因为复制是 定义为从src读取直到EOF,它不会从Read处理EOF 作为要报告的错误。
如果src实现了WriterTo接口,则副本由。实现 调用src.WriteTo(dst)。否则,如果dst实现ReaderFrom 接口,通过调用dst.ReadFrom(src)实现副本。