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

使用Apache FTPClient下载PNG仅服务器1出现损坏的问题求助

问题根源与修复方案

嘿,这个问题我之前处理过好几次!核心问题出在FTP传输模式的选择上——你的代码没有显式指定二进制传输模式,而Apache Commons Net的FTPClient默认使用的是ASCII模式,这对PNG这类二进制文件来说完全不适用。

为什么只有服务器1出问题?

ASCII模式是为文本文件设计的,它会自动转换换行符(比如把Unix的LF转换成Windows的CRLF)。PNG文件的二进制数据里可能包含了被ASCII模式误判为换行符的字节序列,服务器1的FTP服务严格执行了ASCII模式的转换规则,导致额外插入了字节(你看到的4706比4686多了20字节,大概率是多处换行符转换导致的)。

而服务器2、3可能因为FTP配置、文件存储格式的原因,ASCII模式下没有触发换行符转换;至于Total Commander,它会自动识别.png后缀属于二进制文件,默认用二进制模式下载,所以能拿到正确的文件。

修复代码

只需要在登录FTP服务器后,显式设置文件传输类型为二进制即可,修改后的代码片段如下:

FTPClient ftpClient = new FTPClient();
ftpClient.connect("...", PORT);
ftpClient.login("...", "...");

// 关键:设置二进制传输模式,必须在登录后、开始传输前调用
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);

ftpClient.enterLocalPassiveMode();
FTPFile[] imageFiles = ftpClient.listFiles(distantPathForImages);
for (FTPFile imageFile : imageFiles) {
    InputStream inputStream = ftpClient.retrieveFileStream(distantPathForImages + imageFile.getName());
    OutputStream outputStream = new BufferedOutputStream(new FileOutputStream(new File(PATHDESTCSS + imageFile.getName())));
    byte[] bytesArray = new byte[65536];
    int bytesRead;
    while ((bytesRead = inputStream.read(bytesArray)) != -1) {
        outputStream.write(bytesArray, 0, bytesRead);
    }
    outputStream.close();
    inputStream.close();
    ftpClient.completePendingCommand();
}

额外建议

  • 对于所有非文本文件(图片、压缩包、视频等),都必须使用二进制传输模式,避免数据损坏。
  • 如果你需要同时传输文本和二进制文件,记得在切换文件类型时重新调用setFileType方法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:51:46