使用go语言的第三方包:github.com/pkg/sftp和golang.org/x/crypto/ssh实现文件和文件夹传输。
1、创建connect方法:
func connect(user, password, host string, port int) (*sftp.Client, error) { var ( auth []ssh.AuthMethod addr string clientConfig *ssh.ClientConfig sshClient *ssh.Client sftpClient *sftp.Client err error ) // get auth method auth = make([]ssh.AuthMethod, 0) auth = append(auth, ssh.Password(password)) clientConfig = &ssh.ClientConfig{ User: user, Auth: auth, Timeout: 30 * time.Second, HostKeyCallback: ssh.InsecureIgnoreHostKey(), //ssh.FixedHostKey(hostKey), } // connet to ssh addr = fmt.Sprintf("%s:%d", host, port) if sshClient, err = ssh.Dial("tcp", addr, clientConfig); err != nil { return nil, err } // create sftp client if sftpClient, err = sftp.NewClient(sshClient); err != nil { return nil, err } return sftpClient, nil }
2、上传文件
func uploadFile(sftpClient *sftp.Client, localFilePath string, remotePath string) { srcFile, err := os.Open(localFilePath) if err != nil { fmt.Println("os.Open error : ", localFilePath) log.Fatal(err) } defer srcFile.Close() var remoteFileName = path.Base(localFilePath) dstFile, err := sftpClient.Create(path.Join(remotePath, remoteFileName)) if err != nil { fmt.Println("sftpClient.Create error : ", path.Join(remotePath, remoteFileName)) log.Fatal(err) } defer dstFile.Close() ff, err := ioutil.ReadAll(srcFile) if err != nil { fmt.Println("ReadAll error : ", localFilePath) log.Fatal(err) } dstFile.Write(ff) fmt.Println(localFilePath + " copy file to remote server finished!") }
3、上传文件夹
func uploadDirectory(sftpClient *sftp.Client, localPath string, remotePath string) { localFiles, err := ioutil.ReadDir(localPath) if err != nil { log.Fatal("read dir list fail ", err) } for _, backupDir := range localFiles { localFilePath := path.Join(localPath, backupDir.Name()) remoteFilePath := path.Join(remotePath, backupDir.Name()) if backupDir.IsDir() { sftpClient.Mkdir(remoteFilePath) uploadDirectory(sftpClient, localFilePath, remoteFilePath) } else { uploadFile(sftpClient, path.Join(localPath, backupDir.Name()), remotePath) } } fmt.Println(localPath + " copy directory to remote server finished!") }
4、上传测试
func DoBackup(host string, port int, userName string, password string, localPath string, remotePath string) { var ( err error sftpClient *sftp.Client ) start := time.Now() sftpClient, err = connect(userName, password, host, port) if err != nil { log.Fatal(err) } defer sftpClient.Close() _, errStat := sftpClient.Stat(remotePath) if errStat != nil { log.Fatal(remotePath + " remote path not exists!") } backupDirs, err := ioutil.ReadDir(localPath) if err != nil { log.Fatal(localPath + " local path not exists!") }uploadDirectory(sftpClient, localPath, remotePath)}elapsed := time.Since(start)fmt.Println("elapsed time : ", elapsed)