12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- package send
- import (
- "context"
- "fmt"
- "github.com/gogf/gf/v2/errors/gerror"
- "github.com/gogf/gf/v2/frame/g"
- "github.com/pkg/sftp"
- "golang.org/x/crypto/ssh"
- "io"
- "os"
- "path/filepath"
- "strings"
- "time"
- )
- func UpLoadFilesToSftp(ctx context.Context, fullPath string) error {
- // SFTP 连接配置
- var (
- config = &ssh.ClientConfig{
- User: g.Cfg().MustGet(ctx, "sftp.user").String(), // 替换为你的用户名
- Auth: []ssh.AuthMethod{
- ssh.Password(g.Cfg().MustGet(ctx, "sftp.pwd").String()), // 替换为你的密码
- },
- HostKeyCallback: ssh.InsecureIgnoreHostKey(), // 生产环境应使用 ssh.FixedHostKey
- Timeout: 30 * time.Second,
- }
- successNum int
- failPath []string
- )
- info, err := os.Stat(fullPath)
- if err != nil {
- return gerror.Wrap(err, "读取文件失败")
- }
- g.Log().Infof(ctx, "文件: %s (大小: %d bytes)", fullPath, info.Size())
- // 上传文件
- uploadErr := uploadToSFTP(config, g.Cfg().MustGet(ctx, "sftp.addr").String(), fullPath, strings.Replace(fullPath, "out/", "", 1))
- if uploadErr != nil {
- failPath = append(failPath, fullPath)
- return gerror.Wrapf(err, "%s 文件上传失败", fullPath)
- } else {
- successNum++
- g.Log().Infof(ctx, "%s 文件上传成功!", fullPath)
- }
- return nil
- }
- // 上传文件到SFTP服务器
- func uploadToSFTP(config *ssh.ClientConfig, addr, localPath, remotePath string) error {
- // 1. 建立SSH连接
- sshClient, err := ssh.Dial("tcp", addr, config)
- if err != nil {
- return fmt.Errorf("SSH连接失败: %w", err)
- }
- defer sshClient.Close()
- // 2. 创建SFTP客户端
- sftpClient, err := sftp.NewClient(sshClient)
- if err != nil {
- return fmt.Errorf("创建SFTP客户端失败: %w", err)
- }
- defer sftpClient.Close()
- // 3. 打开本地文件
- localFile, err := os.Open(localPath)
- if err != nil {
- return fmt.Errorf("打开本地文件失败: %w", err)
- }
- defer localFile.Close()
- // 4. 确保远程目录存在
- remoteDir := filepath.Dir(remotePath)
- if err := sftpClient.MkdirAll(remoteDir); err != nil {
- return fmt.Errorf("创建远程目录失败: %w", err)
- }
- // 5. 创建远程文件
- remoteFile, err := sftpClient.Create(remotePath)
- if err != nil {
- return fmt.Errorf("创建远程文件失败: %w", err)
- }
- defer remoteFile.Close()
- // 6. 复制文件内容
- if _, err := io.Copy(remoteFile, localFile); err != nil {
- return fmt.Errorf("复制文件内容失败: %w", err)
- }
- return nil
- }
|