使用Golang从SFTP服务器下载所有文件的方法
使用Golang从SFTP服务器下载所有文件的方法 你好
如何从SFTP服务器下载所有文件?
6 回复
这里有一个很好的教程:如何使用 Go 连接 SFTP
更多关于使用Golang从SFTP服务器下载所有文件的方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
是的,但不行,因为那样做需要列出所有文件,而使用这个方法无法递归列出SFTP服务器上的所有文件。
那么你的意思是你需要递归地处理子目录吗?如果是这样,请检查 listFiles 函数,当遇到目录时,只需再次调用该函数并传入当前目录的名称。
func main() {
fmt.Println("hello world")
}
我认为我们需要你提供更多细节,以及你目前已经尝试过的方法。
例如:我想连接到包含文件 a、aa、ab、aaa、di 以及 do pz 文件夹的服务器 a,并通过我的 Go 脚本下载所有这些文件。
可以使用 github.com/pkg/sftp 包配合 golang.org/x/crypto/ssh 包来实现从SFTP服务器批量下载文件。以下是完整的示例代码:
package main
import (
"fmt"
"io"
"os"
"path/filepath"
"time"
"golang.org/x/crypto/ssh"
"github.com/pkg/sftp"
)
func downloadAllFilesFromSFTP(host, user, password, remoteDir, localDir string) error {
// SSH客户端配置
config := &ssh.ClientConfig{
User: user,
Auth: []ssh.AuthMethod{
ssh.Password(password),
},
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
Timeout: 30 * time.Second,
}
// 连接到SSH服务器
conn, err := ssh.Dial("tcp", host+":22", config)
if err != nil {
return fmt.Errorf("SSH连接失败: %v", err)
}
defer conn.Close()
// 创建SFTP客户端
client, err := sftp.NewClient(conn)
if err != nil {
return fmt.Errorf("SFTP客户端创建失败: %v", err)
}
defer client.Close()
// 获取远程目录下的所有文件
files, err := client.ReadDir(remoteDir)
if err != nil {
return fmt.Errorf("读取远程目录失败: %v", err)
}
// 确保本地目录存在
if err := os.MkdirAll(localDir, 0755); err != nil {
return fmt.Errorf("创建本地目录失败: %v", err)
}
// 遍历并下载所有文件
for _, file := range files {
if file.IsDir() {
continue // 跳过子目录,只下载文件
}
remotePath := filepath.Join(remoteDir, file.Name())
localPath := filepath.Join(localDir, file.Name())
// 打开远程文件
remoteFile, err := client.Open(remotePath)
if err != nil {
fmt.Printf("打开远程文件 %s 失败: %v\n", remotePath, err)
continue
}
// 创建本地文件
localFile, err := os.Create(localPath)
if err != nil {
remoteFile.Close()
fmt.Printf("创建本地文件 %s 失败: %v\n", localPath, err)
continue
}
// 复制文件内容
_, err = io.Copy(localFile, remoteFile)
remoteFile.Close()
localFile.Close()
if err != nil {
fmt.Printf("下载文件 %s 失败: %v\n", remotePath, err)
os.Remove(localPath) // 删除不完整的文件
} else {
fmt.Printf("成功下载: %s -> %s\n", remotePath, localPath)
}
}
return nil
}
func main() {
// 使用示例
err := downloadAllFilesFromSFTP(
"sftp.example.com",
"username",
"password",
"/remote/path",
"./local/downloads",
)
if err != nil {
fmt.Printf("下载失败: %v\n", err)
} else {
fmt.Println("所有文件下载完成")
}
}
如果需要包含子目录的递归下载,可以使用以下递归版本:
func downloadRecursive(client *sftp.Client, remotePath, localPath string) error {
// 获取远程文件信息
info, err := client.Stat(remotePath)
if err != nil {
return err
}
if info.IsDir() {
// 创建本地目录
if err := os.MkdirAll(localPath, 0755); err != nil {
return err
}
// 读取目录内容
files, err := client.ReadDir(remotePath)
if err != nil {
return err
}
// 递归处理每个项目
for _, file := range files {
remoteFilePath := filepath.Join(remotePath, file.Name())
localFilePath := filepath.Join(localPath, file.Name())
if err := downloadRecursive(client, remoteFilePath, localFilePath); err != nil {
return err
}
}
} else {
// 下载单个文件
remoteFile, err := client.Open(remotePath)
if err != nil {
return err
}
defer remoteFile.Close()
localFile, err := os.Create(localPath)
if err != nil {
return err
}
defer localFile.Close()
if _, err := io.Copy(localFile, remoteFile); err != nil {
return err
}
}
return nil
}
使用前需要安装依赖:
go get golang.org/x/crypto/ssh
go get github.com/pkg/sftp
这个实现包含了错误处理、连接管理和文件传输的基本功能。

