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

Android使用commons-net-3.6-ftp下载FTP文件缺失约2KB致损坏

FTP文件下载缺失数据问题修复方案

核心问题点

  1. 循环内提前断开连接:遍历文件时每处理一个文件就调用disconnect(),导致FTP传输未完成收尾流程,同时后续文件无法正常建立传输连接。
  2. 未完成FTP传输确认:使用retrieveFileStream获取输入流后,未调用completePendingCommand(),服务器端剩余的缓冲数据无法完全传输到本地,导致文件末尾缺失。
  3. 流资源管理不规范:未正确关闭输入流,也未利用自动资源管理机制确保流数据完全刷新。

修复后的下载代码

fun download(url: MapFragment) {
    try {
        ftpClient?.changeWorkingDirectory("mapa/${url.shortName}") ?: return

        listener?.mapDownloadStarted()
        val pathh = context?.getExternalFilesDir(null) ?: return
        val files = ftpClient?.listFiles() ?: return

        files.forEach { ftpFile ->
            val destFile = File(pathh, "ptv/maps/${ftpFile.name}")
            // 确保目标目录存在,避免文件创建失败
            destFile.parentFile?.mkdirs()

            // 使用use自动管理流资源,无需手动关闭
            BufferedOutputStream(FileOutputStream(destFile)).use { desFileStream ->
                ftpClient?.retrieveFileStream(ftpFile.name)?.use { input ->
                    org.apache.commons.net.io.Util.copyStream(input, desFileStream)
                    desFileStream.flush()
                }
                // 必须调用此方法确认FTP服务器的传输完成信号
                ftpClient?.completePendingCommand()
            }
        }
        // 所有文件下载完成后统一断开连接
        ftpClient?.disconnect()
    } catch (e: Exception) {
        logE(e.toString())
    }
}

额外注意事项

  • 确认FTP配置中已正确设置二进制传输模式:mFtpClient.setFileType(FTP.BINARY_FILE_TYPE),避免文本模式下的换行符转换导致文件结构损坏。
  • 被动模式enterLocalPassiveMode()配置正确,可避免防火墙或网络环境限制导致的传输中断。
  • 若使用retrieveFile方法简化实现,需确保参数传递正确,示例如下:
// 使用retrieveFile的简化写法
ftpClient?.retrieveFile(ftpFile.name, FileOutputStream(destFile))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 18:22:36