gpt4 book ai didi

amazon-web-services - 使用 golang 无法将文件上传到 SFTP 主机

转载 作者:行者123 更新时间:2023-12-01 22:28:16 24 4
gpt4 key购买 nike

我有以下 golang 函数可以将文件上传到 SFTP:

func uploadObjectToDestination(sshConfig SSHConnectionConfig, destinationPath string, srcFile io.Reader) {
// Connect to destination host via SSH
conn, err := ssh.Dial("tcp", sshConfig.sftpHost+sshConfig.sftpPort, sshConfig.authConfig)
if err != nil {
log.Fatal(err)
}
defer conn.Close()

// create new SFTP client
client, err := sftp.NewClient(conn)
if err != nil {
log.Fatal(err)
}
defer client.Close()

log.Printf("Opening file on destination server under path %s", destinationPath)
// create destination file
dstFile, err := client.OpenFile(destinationPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC)
if err != nil {
log.Fatal(err)
}
defer dstFile.Close()

log.Printf("Copying file to %s", destinationPath)
// copy source file to destination file
bytes, err := io.Copy(dstFile, srcFile)
if err != nil {
log.Fatal(err)
}

log.Printf("%s - Total %d bytes copied\n", dstFile.Name(), bytes)
}

上面的代码适用于 95% 的情况,但对于某些文件失败。失败的文件之间的唯一关系是大小(3-4kb)。其他成功的文件更小(0.5-3kb)。在某些情况下,大小为 2-3kb 的文件也会失败。

我能够使用不同的 SFTP 服务器重现相同的问题。

使用 io.Copy 更改失败代码 ( sftp.Write ) 时我可以看到相同的行为,除了该过程没有返回错误,而是我看到复制了 0 个字节,这似乎与 io.Copy 失败相同。

顺便说一句,当使用 io.Copy ,我收到的错误是 Context cancelled, unexpected EOF .

代码从 AWS lambda 运行,没有内存或时间限制问题。

最佳答案

经过几个小时的挖掘,事实证明,我的代码是问题的根源。
以下是 future 引用的答案:
原始问题中没有另一个函数从 S3 下载对象:

    func getObjectFromS3(svc *s3.S3, bucket, key string) io.Reader {
var timeout = time.Second * 30
ctx := context.Background()
var cancelFn func()
ctx, cancelFn = context.WithTimeout(ctx, timeout)
defer cancelFn()
var input = &s3.GetObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(key),
}
o, err := svc.GetObjectWithContext(ctx, input)
if err != nil {
if aerr, ok := err.(awserr.Error); ok && aerr.Code() == request.CanceledErrorCode {
log.Fatal("Download canceled due to timeout", err)
} else {
log.Fatal("Failed to download object", err)
}
}
// Load S3 file into memory, assuming small files
return o.Body
}

上面的代码使用上下文,由于某种原因,返回的对象大小是错误的。
因为我在这里不使用上下文,所以我只是将我的代码转换为使用解决问题的 GetObject(input)。
func getObjectFromS3(svc *s3.S3, bucket, key string) io.Reader {
var input = &s3.GetObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(key),
}

o, err := svc.GetObject(input)
if err != nil {
if aerr, ok := err.(awserr.Error); ok {
switch aerr.Code() {
case s3.ErrCodeNoSuchKey:
log.Fatal(s3.ErrCodeNoSuchKey, aerr.Error())
default:
log.Fatal(aerr.Error())
}
} else {
// Print the error, cast err to awserr.Error to get the Code and
// Message from an error.
log.Fatal(err.Error())
}
}

// Load S3 file into memory, assuming small files
return o.Body
}

关于amazon-web-services - 使用 golang 无法将文件上传到 SFTP 主机,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58449450/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com