gpt4 book ai didi

go语言实现sftp包上传文件和文件夹到远程服务器操作

转载 作者:qq735679552 更新时间:2022-09-27 22:32:09 26 4
gpt4 key购买 nike

CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.

这篇CFSDN的博客文章go语言实现sftp包上传文件和文件夹到远程服务器操作由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.

使用go语言的第三方包:github.com/pkg/sftp和golang.org/x/crypto/ssh实现文件和文件夹传输.

1、创建connect方法:

  。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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、上传文件

  。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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、上传文件夹

  。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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、上传测试

  。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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)
}

补充:go实现ssh远程机器并传输文件 。

核心依赖包:

golang.org/x/crypto/ssh 。

github.com/pkg/sftp 。

其中golang.org/x/crypto/ssh 可从github上下载, 。

下载地址:https://github.com/golang/crypto 。

ssh连接源码(这里是根据秘钥连接)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
var keypath = "key/id_rsa"
//获取秘钥
func publicKey(path string) ssh.AuthMethod {
  keypath, err := homedir.Expand(path)
  if err != nil {
  fmt.Println("获取秘钥路径失败", err)
  }
  key, err1 := ioutil.ReadFile(keypath)
  if err1 != nil {
  fmt.Println("读取秘钥失败", err1)
  }
  signer, err2 := ssh.ParsePrivateKey(key)
  if err2 != nil {
  fmt.Println("ssh 秘钥签名失败", err2)
  }
  return ssh.PublicKeys(signer)
}
//获取ssh连接
func GetSSHConect(ip, user string, port int) (*ssh.Client) {
  con := &ssh.ClientConfig{
  User: user,
  Auth: []ssh.AuthMethod{publicKey(keypath)},
  HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
  return nil
  },
  }
  addr := fmt.Sprintf("%s:%d", ip, port)
  client, err := ssh.Dial("tcp", addr, con)
  if err != nil {
  fmt.Println("Dail failed: ", err)
  panic(err)
  }
  return client
}
// 远程执行脚本
func Exec_Task(ip, user, localpath, remotepath string) int {
  port := 22
  client := GetSSHConect(ip, user, port)
  UploadFile(ip, user, localpath, remotepath, port)
  session, err := client.NewSession()
  if err != nil {
  fmt.Println("创建会话失败", err)
  panic(err)
  }
  defer session.Close()
  remoteFileName := path.Base(localpath)
  dstFile := path.Join(remotepath, remoteFileName)
  err1 := session.Run(fmt.Sprintf("/usr/bin/sh %s", dstFile))
  if err1 != nil {
  fmt.Println("远程执行脚本失败", err1)
  return 2
  } else {
  fmt.Println("远程执行脚本成功")
  return 1
  }
}

文件传输功能:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
//获取ftp连接
func getftpclient(client *ssh.Client) (*sftp.Client) {
  ftpclient, err := sftp.NewClient(client)
  if err != nil {
  fmt.Println("创建ftp客户端失败", err)
  panic(err)
  }
  return ftpclient
}
//上传文件
func UploadFile(ip, user, localpath, remotepath string, port int) {
  client := GetSSHConect(ip, user, port)
  ftpclient := getftpclient(client)
  defer ftpclient.Close()
  remoteFileName := path.Base(localpath)
  fmt.Println(localpath, remoteFileName)
  srcFile, err := os.Open(localpath)
  if err != nil {
  fmt.Println("打开文件失败", err)
  panic(err)
  }
  defer srcFile.Close()
  dstFile, e := ftpclient.Create(path.Join(remotepath, remoteFileName))
  if e != nil {
  fmt.Println("创建文件失败", e)
  panic(e)
  }
  defer dstFile.Close()
  buffer := make([]byte, 1024)
  for {
  n, err := srcFile.Read(buffer)
  if err != nil {
  if err == io.EOF {
  fmt.Println("已读取到文件末尾")
  break
  } else {
  fmt.Println("读取文件出错", err)
  panic(err)
  }
  }
  dstFile.Write(buffer[:n])
  //注意,由于文件大小不定,不可直接使用buffer,否则会在文件末尾重复写入,以填充1024的整数倍
  }
  fmt.Println("文件上传成功")
}
//文件下载
func DownLoad(ip, user, localpath, remotepath string, port int) {
  client := GetSSHConect(ip, user, port)
  ftpClient := getftpclient(client)
  defer ftpClient.Close()
  srcFile, err := ftpClient.Open(remotepath)
  if err != nil {
  fmt.Println("文件读取失败", err)
  panic(err)
  }
  defer srcFile.Close()
  localFilename := path.Base(remotepath)
  dstFile, e := os.Create(path.Join(localpath, localFilename))
  if e != nil {
  fmt.Println("文件创建失败", e)
  panic(e)
  }
  defer dstFile.Close()
  if _, err1 := srcFile.WriteTo(dstFile); err1 != nil {
  fmt.Println("文件写入失败", err1)
  panic(err1)
  }
  fmt.Println("文件下载成功")
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我。如有错误或未考虑完全的地方,望不吝赐教.

原文链接:https://blog.csdn.net/fu_qin/article/details/78741854 。

最后此篇关于go语言实现sftp包上传文件和文件夹到远程服务器操作的文章就讲到这里了,如果你想了解更多关于go语言实现sftp包上传文件和文件夹到远程服务器操作的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

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