send.go 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. package send
  2. import (
  3. "context"
  4. "fmt"
  5. "github.com/gogf/gf/v2/errors/gerror"
  6. "github.com/gogf/gf/v2/frame/g"
  7. "github.com/pkg/sftp"
  8. "golang.org/x/crypto/ssh"
  9. "io"
  10. "os"
  11. "path/filepath"
  12. "strings"
  13. "time"
  14. )
  15. func UpLoadFilesToSftp(ctx context.Context, fullPath string) error {
  16. // SFTP 连接配置
  17. var (
  18. config = &ssh.ClientConfig{
  19. User: g.Cfg().MustGet(ctx, "sftp.user").String(), // 替换为你的用户名
  20. Auth: []ssh.AuthMethod{
  21. ssh.Password(g.Cfg().MustGet(ctx, "sftp.pwd").String()), // 替换为你的密码
  22. },
  23. HostKeyCallback: ssh.InsecureIgnoreHostKey(), // 生产环境应使用 ssh.FixedHostKey
  24. Timeout: 30 * time.Second,
  25. }
  26. successNum int
  27. failPath []string
  28. )
  29. info, err := os.Stat(fullPath)
  30. if err != nil {
  31. return gerror.Wrap(err, "读取文件失败")
  32. }
  33. g.Log().Infof(ctx, "文件: %s (大小: %d bytes)", fullPath, info.Size())
  34. // 上传文件
  35. uploadErr := uploadToSFTP(config, g.Cfg().MustGet(ctx, "sftp.addr").String(), fullPath, strings.Replace(fullPath, "out/", "", 1))
  36. if uploadErr != nil {
  37. failPath = append(failPath, fullPath)
  38. return gerror.Wrapf(err, "%s 文件上传失败", fullPath)
  39. } else {
  40. successNum++
  41. g.Log().Infof(ctx, "%s 文件上传成功!", fullPath)
  42. }
  43. return nil
  44. }
  45. // 上传文件到SFTP服务器
  46. func uploadToSFTP(config *ssh.ClientConfig, addr, localPath, remotePath string) error {
  47. // 1. 建立SSH连接
  48. sshClient, err := ssh.Dial("tcp", addr, config)
  49. if err != nil {
  50. return fmt.Errorf("SSH连接失败: %w", err)
  51. }
  52. defer sshClient.Close()
  53. // 2. 创建SFTP客户端
  54. sftpClient, err := sftp.NewClient(sshClient)
  55. if err != nil {
  56. return fmt.Errorf("创建SFTP客户端失败: %w", err)
  57. }
  58. defer sftpClient.Close()
  59. // 3. 打开本地文件
  60. localFile, err := os.Open(localPath)
  61. if err != nil {
  62. return fmt.Errorf("打开本地文件失败: %w", err)
  63. }
  64. defer localFile.Close()
  65. // 4. 确保远程目录存在
  66. remoteDir := filepath.Dir(remotePath)
  67. if err := sftpClient.MkdirAll(remoteDir); err != nil {
  68. return fmt.Errorf("创建远程目录失败: %w", err)
  69. }
  70. // 5. 创建远程文件
  71. remoteFile, err := sftpClient.Create(remotePath)
  72. if err != nil {
  73. return fmt.Errorf("创建远程文件失败: %w", err)
  74. }
  75. defer remoteFile.Close()
  76. // 6. 复制文件内容
  77. if _, err := io.Copy(remoteFile, localFile); err != nil {
  78. return fmt.Errorf("复制文件内容失败: %w", err)
  79. }
  80. return nil
  81. }