Android: How can I get the file size of a FTP file via FTPClient?
Asked Answered
O

3

11

How can I read the file size of a file that is stored on my ftp server? I don't like to implement another libary.

I am working with commons-io-2.4 and commons-net-3.1

Answer and code from talhakosen (thanks!)

private long getFileSize(FTPClient ftp, String filePath) throws Exception {
    long fileSize = 0;
    FTPFile[] files = ftp.listFiles(filePath);
    if (files.length == 1 && files[0].isFile()) {
        fileSize = files[0].getSize();
    }
    Log.i(TAG, "File size = " + fileSize);
    return fileSize;
}
Obstruct answered 16/11, 2012 at 10:32 Comment(0)
P
7

Hi you can use the code below,

private void ftpDownload() {
    FTPClient ftp = null;
    try {
        ftp = new FTPClient();
        ftp.connect(mServer);

        try {
            int reply = ftp.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                throw new Exception("Connect failed: " + ftp.getReplyString());
            }
            if (!ftp.login(mUser, mPassword)) {
                throw new Exception("Login failed: " + ftp.getReplyString());
            }
            try {
                ftp.enterLocalPassiveMode();
                if (!ftp.setFileType(FTP.BINARY_FILE_TYPE)) {
                    Log.e(TAG, "Setting binary file type failed.");
                }
                transferFile(ftp);
            } catch(Exception e) {
                handleThrowable(e);
            } finally {
                if (!ftp.logout()) {
                    Log.e(TAG, "Logout failed.");
                }
            }
        } catch(Exception e) {
            handleThrowable(e);
        } finally {
            ftp.disconnect();
        }
    } catch(Exception e) {
        handleThrowable(e);
    }
}

private void transferFile(FTPClient ftp) throws Exception {
    long fileSize = getFileSize(ftp, mFilePath);
    InputStream is = retrieveFileStream(ftp, mFilePath);
    downloadFile(is, buffer, fileSize);
    is.close();

    if (!ftp.completePendingCommand()) {
        throw new Exception("Pending command failed: " + ftp.getReplyString());
    }
}

private InputStream retrieveFileStream(FTPClient ftp, String filePath)
throws Exception {
    InputStream is = ftp.retrieveFileStream(filePath);
    int reply = ftp.getReplyCode();
    if (is == null
            || (!FTPReply.isPositivePreliminary(reply)
                    && !FTPReply.isPositiveCompletion(reply))) {
        throw new Exception(ftp.getReplyString());
    }
    return is;
}

private byte[] downloadFile(InputStream is, long fileSize)
throws Exception {
    byte[] buffer = new byte[fileSize];
    if (is.read(buffer, 0, buffer.length)) == -1) {
        return null;
    }
    return buffer; // <-- Here is your file's contents !!!
}

private long getFileSize(FTPClient ftp, String filePath) throws Exception {
    long fileSize = 0;
    FTPFile[] files = ftp.listFiles(filePath);
    if (files.length == 1 && files[0].isFile()) {
        fileSize = files[0].getSize();
    }
    Log.i(TAG, "File size = " + fileSize);
    return fileSize;
}
Phillida answered 16/11, 2012 at 10:39 Comment(0)
E
0

If the server does not allow the client to list the files. you can try size cmd. please see Extensions to FTP RFC3659 for the size FTP cmd syntax. you also can use the following function example.

private long getRemoteSize(FTPClient client, String remoteFilePath) throws Exception {
    client.sendCommand("SIZE", remoteFilePath);
    String[] reply = client.getReplyStrings();
    String[] response = reply[0].split(" ");
    if(client.getReplyCode() != 213){
      throw new Exception(String.format("ftp client size cmd response %d",client.getReplyCode()));
    }
    return Long.parseLong(response[1]);
  };
Epidemic answered 6/5, 2020 at 4:5 Comment(4)
You can use getReplyString to get a single string, no need to use getReplyString. Also don't forget to use trim() before splitting because the reply string might contain a \n at the end. While this code does return the file size, there's something weird going on - at least in my code: Sending another command after sending SIZE (and dealing with the reply) always returns the reply "500 Command not understood." - I tested it with RETR and CWD but always get the same result.Greenfinch
Thanks for the comments. Because the FTP cmd should be isolated. so CWD and RETR should not be impacted by the SIZE cmd. could you try CWD and RETR without SIZE? let's see if the got the same result.Epidemic
Thanks for your reply. CWD and RETR work fine on their own, it's the SIZE command that seems to mess it up somehow. Are you experiencing the same problem?Greenfinch
This indeed seems to be a problem with the library: I'm currently working on rewriting my "login" and "download files" code to use Java's basic Socket instead of the library (because there are also other problems), so basically I'm doing everything "by hand", and sending SIZE, then RETR works perfectly fine with my new code. I then also ran the FTPClient version of the code again because I noticed that I'd forgotten to switch to binary mode there too but it's still returning the 500 error message if SIZE is used.Greenfinch
A
-2
private long getFileSize(FTPClient ftpClient, String fileName) throws Exception 
{
   long fileSize = 0;
   String fileName; 
   //down file name 
   FTPFile[] files = ftpClient.listFiles(); //ftp list
   for ( i = 0; i < files.length; i++)
   { //ftp connect forder in files              
      if (fileName == files[i].getName())
      { 
        fileSize = files[i].getSize();
        return fileSize;
      }
   }         
}         
Artur answered 28/3, 2013 at 4:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.