FTP 使用 Apache Commons Net 下载后文件损坏

FTP file corrupt after download with Apache Commons Net

由此下载的文件,大小几乎相同,但有些行不同。每个答案都指向二进制文件类型。但这无济于事。 有人知道这个问题(传输 PDF)吗?

FTPClient ftpClient = new FTPClient();
OutputStream outputStream = null;
boolean resultOk = true;

try {
    ftpClient.connect(host, port);
    ftpClient.enterLocalPassiveMode();
    ftpClient.setFileTransferMode(FTP.COMPRESSED_TRANSFER_MODE);
    ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
    if (showMessages) {
        System.out.println(ftpClient.getReplyString());
    }
    resultOk &= ftpClient.login(usr, pwd);
    if (showMessages) {
        System.out.println(ftpClient.getReplyString());
    }

    outputStream = new FileOutputStream(localResultFile);
    resultOk &= ftpClient.retrieveFile(remoteSourceFile, outputStream);
    outputStream.flush();
    outputStream.close();

    if (showMessages) {
        System.out.println(ftpClient.getReplyString());
    }
    if (resultOk == true) {
        resultOk &= ftpClient.deleteFile(remoteSourceFile);
    }

    resultOk &= ftpClient.logout();
    if (showMessages) {
        System.out.println(ftpClient.getReplyString());
    }
} finally {

    ftpClient.disconnect();
}

从您共享的文件可以清楚地看出,传输确实发生在 text/ascii 模式下。

虽然 FTP 规范可能不需要,但对于某些 FTP 服务器(例如 FileZilla 服务器或 ProFTPD),您无法在登录前更改传输类型。但是服务器像 IIS,ProFTPD 或 vsftpd 都没有问题。另一方面,无论如何,FileZilla 服务器默认为二进制模式(这是另一种违反规范的行为),因此您可能正在使用另一种模式。

无论如何,将 .setFileType 调用移到 .login 之后。并测试其 return 值。


并删除 .setFileTransferMode 调用。它对大多数服务器没有任何危害,因为几乎没有服务器支持 MODE C,因此该调用无论如何都会被忽略。但是,如果您遇到支持的服务器,它会中断传输,因为 FTPClient 实际上不支持它。

使用包含空格的非转义路径时似乎会发生这种情况。例如。 C:/文档和 Settings/test

现在通过对空格使用转义路径解决了这个问题。感谢您的帮助

虽然我的问题与上传损坏有关,但我通过在 ftp 登录后移动文件类型集解决了类似问题(我不使用传输模式,将其保留为默认值):

resultOk &= ftpClient.login(usr, pwd);
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);

我在一些论坛上看到,在调用登录方法之前设置二进制文件类型,可能会导致传输出现问题。在此更改之前,PDF 文件已下载但显示损坏的字体和元素。现在可以了。希望它可以帮助某人。