一、连接服务器,采用sftp连接模式
go
复制代码
package middlewares
import (
"fmt"
"time"
"github.com/pkg/sftp"
"golang.org/x/crypto/ssh"
)
// 建立服务器连接
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: []ssh.AuthMethod{ssh.Password(password)},
// 此处忽略了密钥认证,改用密码认证
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
Timeout: 30 * time.Second,
}
// 通过ssh连接到服务器
addr = fmt.Sprintf("%s:%d", host, port)
if sshClient, err = ssh.Dial("tcp", addr, clientConfig); err != nil {
return nil, err
}
// 创建一个sftp连接工具用来读取文件或者目录
if sftpClient, err = sftp.NewClient(sshClient); err != nil {
return nil, err
}
return sftpClient, nil
}
二、下载文件
go
复制代码
// 定义下载功能
func SyncCiticLog(r *gin.Context) {
// viper设置的连接服务器的用户名和密码以及端口、连接的IP地址,此用户名写在了配置文件中
User := viper.GetString("ConnectUser")
Password := viper.GetString("ConnectPassword")
Port := viper.GetInt("ConnectPort")
citicIp := viper.GetString("ConnectOldIp")
// 此处设置了要读取的目录前缀
const allDir = "D:\\backup\\citic"
// 定义变量用来接收下载文件的源目录和目标目录
dstDir := ""
srcDir := ""
// 实例化结构体用来接收数据
downloglist := DownLogList{}
// 调用定义的sftp方法连接服务器
sftpClient, sftpErr := middlewares.Connect(User, Password, citicIp, Port)
// 此处要关闭要用defer关闭连接,否则下载的文件将发生打开文件错误
defer sftpClient.Close()
// 判断连接是否成功
if sftpErr != nil {
logs.Error(map[string]interface{}{"msg": sftpErr}, "未连接到服务器,请检查相关配置!")
}
// 此处用的Post请求,在请求体获取前端传递过来的参数
if error := r.ShouldBindBodyWithJSON(&downloglist); error != nil {
logs.Error(map[string]interface{}{"msg": "绑定结构体失败"}, "请检查配置文件是否正确!")
} else {
// 判断传递过来的IP,来定义相应的源目录和目标目录
switch downloglist.ServiceIp {
case "172.16.2.51":
srcDir = "/home/backup/zqyl-abc/new"
dstDir = "D:\\backup\\abc"
break
case "172.16.2.58":
srcDir = "/home/backup/citic/" + downloglist.ServiceIp
dstDir = filepath.Join(allDir, "中信03")
break
case "172.16.2.59":
srcDir = "/home/backup/citic/" + downloglist.ServiceIp
dstDir = filepath.Join(allDir, "中信04")
break
case "172.16.2.60":
srcDir = "/home/backup/citic/" + downloglist.ServiceIp
dstDir = filepath.Join(allDir, "中信01")
break
case "172.16.2.61":
srcDir = "/home/backup/citic/" + downloglist.ServiceIp
dstDir = filepath.Join(allDir, "中信02")
break
}
// 由于传递过来的下载文件是多个,所以将以集合的形式传递过来,循环遍历来将单个文件进行下载
for _, citicLog := range downloglist.LogList {
// 拼出源文件的位置目录
fileSrcDir := srcDir + "/" + citicLog
// 利用sftp连接工具将文件目录打开
openFile, err := sftpClient.Open(fileSrcDir)
if err != nil {
logs.Error(map[string]interface{}{"msg": "读取文件失败!"}, "请检查文件是否存在或者是否正常!")
}
// 创建本地文件存放的目录
error := os.MkdirAll(dstDir, 0755)
if error != nil {
logs.Error(map[string]interface{}{"msg": "创建文件失败!"}, "请检查目录是否存在!")
}
// 创建本地文件的等待拷贝
logFile, _ := os.Create(dstDir + "\\" + citicLog)
// 创建资源记得关闭
defer logFile.Close()
// 拷贝文件至目标目录
_, copyErr := io.Copy(logFile, openFile)
if copyErr != nil {
logs.Info(map[string]interface{}{"msg": "下载文件失败,请检查磁盘分区是否存在或者是否可写入状态!!"}, "")
}
}
// 返回给前端状态码、下载成功信息、目标文件下载到的目录
r.JSON(http.StatusOK, gin.H{
"status": http.StatusOK,
"message": "下载成功!",
"path": dstDir,
})
}
}