You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin Android应用转用SFTP协议传输文件:库、依赖及操作咨询

Kotlin/Android 下的SFTP库选择与基础操作实现

一、可用的SFTP库

Kotlin完全兼容Java生态,成熟的Java SFTP库都能直接在Kotlin项目中使用,常用的有以下几个:

  • JSch:老牌SFTP实现库,功能全面,社区支持完善,是多数项目的首选方案。
  • Apache Commons VFS:提供统一的文件系统访问API,SFTP只是其中一种实现,适合需要同时操作多种文件系统的场景。
  • SSHJ:基于SSH2协议的轻量级库,API设计更简洁现代,性能表现优异。

二、Android Studio依赖引入

根据选择的库,在Module级别的build.gradle(或build.gradle.kts)中添加对应依赖:

1. JSch

dependencies {
    implementation 'com.jcraft:jsch:0.1.55'
}

2. Apache Commons VFS

dependencies {
    implementation 'org.apache.commons:commons-vfs2:2.9.0'
}

3. SSHJ

dependencies {
    implementation 'com.hierynomus:sshj:0.34.0'
}

三、基础SFTP操作实现

以下以JSch为例演示核心操作(JSch使用最广泛,示例参考性更强):

1. 建立SFTP连接

import com.jcraft.jsch.JSch
import com.jcraft.jsch.Session
import com.jcraft.jsch.ChannelSftp

fun createSftpSession(host: String, port: Int, username: String, password: String): ChannelSftp? {
    return try {
        val jsch = JSch()
        val session: Session = jsch.getSession(username, host, port).apply {
            setPassword(password)
            // 生产环境建议配置合法密钥校验,此处为测试跳过校验
            setConfig("StrictHostKeyChecking", "no")
            connect(5000) // 5秒连接超时
        }
        val channel = session.openChannel("sftp") as ChannelSftp
        channel.connect()
        channel
    } catch (e: Exception) {
        e.printStackTrace()
        null
    }
}

2. 文件上传

fun uploadFile(sftpChannel: ChannelSftp, localFilePath: String, remoteDir: String) {
    try {
        // 切换远程目录,不存在则创建
        try {
            sftpChannel.cd(remoteDir)
        } catch (e: Exception) {
            sftpChannel.mkdir(remoteDir)
            sftpChannel.cd(remoteDir)
        }
        // 上传本地文件到当前远程目录
        sftpChannel.put(localFilePath, sftpChannel.pwd())
        println("文件上传成功")
    } catch (e: Exception) {
        e.printStackTrace()
        println("文件上传失败:${e.message}")
    }
}

3. 文件下载

fun downloadFile(sftpChannel: ChannelSftp, remoteFilePath: String, localDir: String) {
    try {
        val fileName = remoteFilePath.split("/").last()
        sftpChannel.get(remoteFilePath, "$localDir/$fileName")
        println("文件下载成功")
    } catch (e: Exception) {
        e.printStackTrace()
        println("文件下载失败:${e.message}")
    }
}

4. 查看远程文件列表

fun listRemoteFiles(sftpChannel: ChannelSftp, remoteDir: String) {
    try {
        sftpChannel.cd(remoteDir)
        val fileList = sftpChannel.ls("*")
        fileList.forEach { file ->
            if (file.filename != "." && file.filename != "..") {
                val type = if (file.isDirectory) "[目录]" else "[文件]"
                println("$type ${file.filename}")
            }
        }
    } catch (e: Exception) {
        e.printStackTrace()
        println("获取文件列表失败:${e.message}")
    }
}

5. 关闭连接

使用后务必关闭资源,避免内存泄漏:

fun closeSftpSession(sftpChannel: ChannelSftp?) {
    sftpChannel?.let {
        if (it.isConnected) it.disconnect()
        it.session?.let { session ->
            if (session.isConnected) session.disconnect()
        }
    }
}

调用示例

fun main() {
    val host = "你的SFTP服务器地址"
    val port = 22 // SFTP默认端口
    val username = "用户名"
    val password = "密码"

    val sftpChannel = createSftpSession(host, port, username, password)
    sftpChannel?.let {
        listRemoteFiles(it, "/")
        uploadFile(it, "/本地文件路径/file.txt", "/远程目标目录")
        downloadFile(it, "/远程目标目录/file.txt", "/本地保存目录")
        closeSftpSession(it)
    } ?: println("SFTP连接建立失败")
}

注意:Android中网络操作必须放在子线程执行,可通过Coroutine或线程池实现;生产环境禁止跳过主机密钥校验,需提前配置服务器公钥到信任列表。

内容的提问来源于stack exchange,提问作者Piotr Radziewicz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 00:38:36