【问题标题】:Images downloaded from "some" servers with FTPClient are corrupted使用 FTPClient 从“某些”服务器下载的图像已损坏
【发布时间】:2018-01-29 13:58:38
【问题描述】:

我需要用 Java 从 FTP 服务器下载 .png 文件。 我有 3 台不同的服务器,每台都包含一个包含完全相同的 .png 文件的文件夹。

在服务器 1 上:
如果我使用 FTPClient (apache.commons.net.ftp) 下载存储在此服务器上的 4686 字节的 .png 文件,我会得到一个 4706 字节的 .png 文件,但我无法打开它。 如果我用 Total Commander 下载它,我会得到一个 4686 字节的 .png 文件,我可以打开它。

在服务器 2 和 3 上:
使用FTPClient 和 Total Commander,我在这两种情况下都得到了一个 4686 字节的文件,我可以毫无问题地打开它。

我的代码:

FTPClient ftpClient = new FTPClient();
ftpClient.connect("...", PORT);
ftpClient.login("...", "...");
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();
}

为什么我的文件只有从服务器 1 下载时才有这些“额外字节”,我该如何解决?

【问题讨论】:

    标签: java ftp apache-commons-net


    【解决方案1】:

    您的一个服务器可能尝试将文件作为文本传输,而您的 ftp 客户端也认为它接收到了文本。

    以下是 javadoc 的摘录:

    如果当前文件类型是ASCII,则返回InputStream 将文件中的行分隔符转换为本地 表示。

    如果你在 Windows 上,每个换行符都会被 'linebreak + cr' 替​​换,对 png 文件中的所有数据结构造成严重破坏。

    此方案的预期字节数为:4686 * (1 + 1 / 256) = 4704.3046875 ,因为平均而言,png 文件中的每 256 个字节应该看起来像一个 ASCII 换行符,因此会导致在额外添加的字节中。您的文件最终有 4706 字节,非常接近。

    将文件类型设置为FTP.BINARY_FILE_TYPE 应该可以解决这个问题:https://commons.apache.org/proper/commons-net/apidocs/org/apache/commons/net/ftp/FTPClient.html#setFileType(int)

    【讨论】:

      【解决方案2】:

      FTPClient默认使用ascii模式。

      你必须使用二进制模式来传输二进制文件。

      ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
      

      如果服务器使用的是 Windows EOL 序列,您当前的代码可能会偶然在 某些服务器上运行,即使在 ascii 模式下,也不会发生转换。即使那样,也可能只是,如果文件偶然不包含任何单独的#13。

      【讨论】:

        猜你喜欢
        • 2012-11-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-05
        • 2019-12-12
        • 2020-07-03
        • 1970-01-01
        • 2014-04-26
        相关资源
        最近更新 更多