0

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

GPI
  • 9,088
  • 2
  • 31
  • 38
Amir Peivandi
  • 349
  • 4
  • 19
  • What concrete steps have you taken to solve this problem yourself? – hd1 Aug 13 '14 at 17:02
  • When you say the downloaded file is smaller, how small is it? What is the contents of the file? Is it an empty file? – hofan41 Aug 13 '14 at 17:08
  • I've tested this on MacOS and Windows and it's always the same result. My original file on the server is 2,612,350 bytes and the downloaded file on MacOS is exactly the same size but the file downloaded on Windows is 2,622,171 bytes. And this is a jar file so the downloaded file on windows is corrupted and can't be used. – Amir Peivandi Aug 13 '14 at 17:22
  • Also initially I was replacing the jar file itself (getting the new version) and even it was woking on Mac I thought maybe this is due to writing on the same file is running in VM! so I added a small helper jar that all it does checks for the actual jar and downloads if there is a new file and then starts a process and then I noticed regardless of that the downloaded file is not coming right. – Amir Peivandi Aug 13 '14 at 17:23

1 Answers1

1

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.

GPI
  • 9,088
  • 2
  • 31
  • 38
  • I do have the setFileTransferMode, I'm setting it to BINARY as you can see in my code. – Amir Peivandi Aug 13 '14 at 17:43
  • setFileTransferMode DOES NOT deal with binary/ASCII transfer, as I wrote. *setFileType* does. You did not do what you thought you were doing. – GPI Aug 13 '14 at 17:44
  • Amazing! That was the issue! It's interesting how this was working fine on Mac and only the issue showed itself on Windows! – Amir Peivandi Aug 13 '14 at 17:58