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
相关产品推荐
相关产品推荐

