使用Go语言通过SFTP协议远程传输文件

橘子海
橘子海
发布时间:2026-10-13 | 5人浏览过
原创

介绍如何利用Go语言和SFTP库,基于SSH协议安全地实现本地与远程服务器之间的文件上传和下载功能,并提供核心连接与IO操作代码。

实现原理与依赖

要实现安全的远程文件传输,通常依赖 SSH(Secure Shell)协议。在 Go 语言中,我们需要组合使用两个核心库:

  • golang.org/x/crypto/ssh:用于建立 SSH 客户端连接并进行身份验证。
  • github.com/pkg/sftp:基于 SSH 协议的 SFTP 客户端库,提供具体的文件读写 API。

连接设置

在进行任何文件操作前,必须先建立稳定的 SSH 隧道并初始化 SFTP 客户端。以下函数封装了连接逻辑,支持密码认证,超时时间设为 30 秒。

第1步:封装SSH与SFTP连接

目的:创建一个可复用的函数,返回 *sftp.Client 对象供后续 IO 操作使用。

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
	)
	// 配置认证方式
	auth = make([]ssh.AuthMethod, 0)
	auth = append(auth, ssh.Password(password))

	clientConfig = &ssh.ClientConfig{
		User:      user,
		Auth:      auth,
		Timeout:   30 * time.Second,
	}

	// 建立 TCP 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
}

发送文件至远程服务器

上传文件需要将本地文件读取并通过缓冲区写入到远端路径。注意处理文件打开、创建及错误返回。

第2步:上传本地文件

入口:sftpClient 连接实例。
动作:读取本地流,逐块写入远端文件。

package main

import (
	"fmt"
	"log"
	"os"
	"path"
	"time"

	"github.com/pkg/sftp"

	"golang.org/x/crypto/ssh"
)

func main() {
	var (
		err        error
		sftpClient *sftp.Client
	)

	// 替换为实际连接的 用户名,密码,主机名或IP,SSH端口
	sftpClient, err = connect("root", "rootpass", "127.0.0.1", 22)
	if err != nil {
		log.Fatal(err)
	}
	defer sftpClient.Close()

	// 定义本地文件路径和目标远程目录
	var localFilePath = "/path/to/local/file/test.txt"
	var remoteDir = "/remote/dir/"
	
	srcFile, err := os.Open(localFilePath)
	if err != nil {
		log.Fatal(err)
	}
	defer srcFile.Close()

	// 构建远端文件名
	var remoteFileName = path.Base(localFilePath)
	dstFile, err := sftpClient.Create(path.Join(remoteDir, remoteFileName))
	if err != nil {
		log.Fatal(err)
	}
	defer dstFile.Close()

	// 循环读取并写入,模拟数据流动
	buf := make([]byte, 1024)
	for {
		n, _ := srcFile.Read(buf)
		if n == 0 {
			break
		}
		dstFile.Write(buf)
	}

	fmt.Println("copy file to remote server finished!")
}

从远程服务器获取文件

下载操作是上传的逆过程,需要从远端读取数据并写入到本地新创建的文件中。推荐使用 WriteTo 方法简化 IO 拷贝流程。

第3步:下载远程文件

入口:sftpClient 连接实例。
动作:打开远端文件,将其写入本地指定目录。

package main

import (
	"fmt"
	"log"
	"os"
	"path"
	"time"

	"github.com/pkg/sftp"

	"golang.org/x/crypto/ssh"
)

func main() {

	var (
		err        error
		sftpClient *sftp.Client
	)

	// 替换为实际连接的 用户名,密码,主机名或IP,SSH端口
	sftpClient, err = connect("root", "rootpass", "127.0.0.1", 22)
	if err != nil {
		log.Fatal(err)
	}
	defer sftpClient.Close()

	// 定义远程源文件和本地目标目录
	var remoteFilePath = "/path/to/remote/path/test.txt"
	var localDir = "/local/dir"

	srcFile, err := sftpClient.Open(remoteFilePath)
	if err != nil {
		log.Fatal(err)
	}
	defer srcFile.Close()

	// 构建本地文件名并创建文件
	var localFileName = path.Base(remoteFilePath)
	dstFile, err := os.Create(path.Join(localDir, localFileName))
	if err != nil {
		log.Fatal(err)
	}
	defer dstFile.Close()

	// 使用 WriteTo 高效完成复制
	if _, err = srcFile.WriteTo(dstFile); err != nil {
		log.Fatal(err)
	}

	fmt.Println("copy file from remote server finished!")
}

总结

上述代码展示了基本的点对点文件传输逻辑。若需实现整个文件夹的同步传输,需在代码中加入递归遍历本地/远程目录树以及根据远端信息创建相应目录的步骤,具体可用函数可参考 sftp 库文档。以上就是使用Go语言实现远程传输文件的详细内容,更多关于Go语言开发技巧的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表