Search code examples
javaftp-clientapache-commons-net

Apache FTPClient


I'm writing a very simple FTPClient application using Apache's library.

All I do is download a jar file from a server. There is no exception, the application works fine when I run in on MacOS and as soon as I run the same code in Windows the downloaded file is smaller than the file on server. However, there is no exception and everything seems to be fine.

I'm going crazy, I'm using binary mode and the code is so simple I can't believe I've been stuck on it since yesterday!!!

Please help!

public boolean loadLatest(){
    FTPClient ftp = new FTPClient();
    try {
        ftp.connect("server address");
        ftp.setControlKeepAliveTimeout(300);
        ftp.enterLocalPassiveMode();
        String fu = "username";
        ftp.login(fu, "password");
        int reply = ftp.getReplyCode();
        if (FTPReply.isPositiveCompletion(reply)) {
            ftp.setFileTransferMode(FTP.BINARY_FILE_TYPE);
            ftp.enterLocalPassiveMode();
            FTPFilter filter = new FTPFilter(); 
            FTPFile[] finfo = ftp.listFiles(".",filter);
            if (finfo.length==0){
                return false;
            }

            File currentJar = new File("sm.jar");

            FileOutputStream output;
            output = new FileOutputStream("sm.jar");
            if (ftp.retrieveFile(finfo[0].getName(), output)==false){
                    System.out.println("Bad file!");
            }
            output.close();             
            ftp.logout();
        }
    } catch (Exception e) {
        e.printStackTrace();
        return false;
    }

    return true;
}

Here is my code:

Thanks


Solution

  • You may have misused the Apache API.

    public boolean setFileTransferMode(int mode) throws IOException

    Sets the transfer mode. The default transfer mode FTP.STREAM_TRANSFER_MODE if this method is never called or if a connect method is called.

    The possible values are STREAM_TRANSFER_MODE, STREAM_TRANSFER_MODE, or BLOCK_TRANSFER_MODE.

    So your following line :

    ftp.setFileTransferMode(FTP.BINARY_FILE_TYPE);
    

    Is not valid use of the API, and does not setup the client to work in BINARY mode.

    The FTP transfert mode as you call it, is actually controled by another method :

    public boolean setFileType(int fileType) throws IOException

    Sets the file type to be transferred. This should be one of FTP.ASCII_FILE_TYPE , FTP.BINARY_FILE_TYPE, etc. The file type only needs to be set when you want to change the type. After changing it, the new type stays in effect until you change it again. The default file type is FTP.ASCII_FILE_TYPE if this method is never called. The server default is supposed to be ASCII (see RFC 959), however many ftp servers default to BINARY. To ensure correct operation with all servers, always specify the appropriate file type after connecting to the server.

    N.B. currently calling any connect method will reset the type to FTP.ASCII_FILE_TYPE.

    Most probably, you need to use this last method to change the mode to BINARY, and your transfer should be OK.