javaftpapache-commons-net

Apache Java FTP client does not switch to binary transfer mode on some servers


I'm using org.apache.commons.net.ftp library to work with FTP servers. I use about 5 FTP servers and one of them doesn't work properly (for me). For uploading files I also use method ftpClient.setFileType(FTP.BINARY_FILE_TYPE), but on this server the size of the uploaded file is not the same as on my local HDD. It is usually MP3 files and when I try to play uploaded MP3 there is some buzz. I suspects that FTP server has wrong configuration, but the company which takes care of this server would be very unlikely to do some changes. One more very important note: when I use Total Commander or WinSCP to upload file, the uploaded file is correct with same size.

Here is my code:

public class FtpConnection {
    String FTP_SERVER;
    String FTP_USER;
    String FTP_PASSWORD;
    int FTP_PORT;
    FTPClient ftpClient;
    int attempts = 3;
    long FILE_SIZE;

    public FtpConnection() {
        FTP_SERVER = StradaAd.FTP_SERVER;
        FTP_USER = StradaAd.FTP_USER;
        FTP_PASSWORD = StradaAd.FTP_PASSWORD;
        FTP_PORT = StradaAd.FTP_PORT;

        ftpClient = new FTPClient();

        ftpClient.setCopyStreamListener(streamListener);

        ftpClient.setBufferSize(1024 * 1024 * 1024);
        ftpClient.setConnectTimeout(240000);
        ftpClient.setDataTimeout(240000);
        try {
            ftpClient.connect(FTP_SERVER, FTP_PORT);
            ftpClient.setControlKeepAliveTimeout(300);
            ftpClient.enterLocalPassiveMode();
            ftpClient.setFileType(FTP.BINARY_FILE_TYPE);

            int replyCode = ftpClient.getReplyCode();
            if (!FTPReply.isPositiveCompletion(replyCode)) {
                StradaAd.errorArea.append("Operation failed. Server reply code: " + replyCode);
                return;
            }
            boolean success = ftpClient.login(FTP_USER, FTP_PASSWORD);

            if (!success) {
                //unsuccess
            }
        } catch (IOException ex) {
          //error
        }
    }

    public boolean uploadFile(File source, String destination, String chain) {
        try {
            FILE_SIZE = source.length();

            ftpClient.cwd("//" + chain + "/REKLAMY/");

            for(int i=0;i<attempts;i++) {
                ftpClient.storeFile(destination, new FileInputStream(source));

                for(FTPFile f : ftpClient.listFiles()) {
                    if(f.getName().equals(destination) && f.getSize() == source.length())
                        return true;
                }
            }
            return false;
        } catch (IOException ex) {
            Logger.getLogger(FtpConnection.class.getName()).log(Level.SEVERE, null, ex);
            return false;
        }
    }    
}

Do someone know the solution how to change this code or set this FTP server to have the same size uploaded file? Thanks in advance for any help.


Solution

  • You call the FTPClient.setFileType method too early.

    At least the ProFTPD or FileZilla FTP servers reset the default transfer mode after the authentication (FTPClient.login).

    Move the .setFileType call after the .login.