Resume a Java FTP file download

apache-commons-net, ftp, java

Solution

Things to know:

FileOutputStream has an append parameter, from doc;

@param append if `true`, then bytes will be written to the end of the file rather than the beginning

FileClient has setRestartOffset which takes offset as parameter, from doc;

@param offset The offset into the remote file at which to start the next file transfer. This must be a value greater than or equal to zero.

We need to combine these two;

boolean downloadFile(String remoteFilePath, String localFilePath) {
  try {
    File localFile = new File(localFilePath);
    if (localFile.exists()) {
      // If file exist set append=true, set ofset localFile size and resume
      OutputStream fos = new FileOutputStream(localFile, true);
      ftp.setRestartOffset(localFile.length());
      ftp.retrieveFile(remoteFilePath, fos);
    } else {
      // Create file with directories if necessary(safer) and start download
      localFile.getParentFile().mkdirs();
      localFile.createNewFile();
      val fos = new FileOutputStream(localFile);
      ftp.retrieveFile(remoteFilePath, fos);
    }
  } catch (Exception ex) {
    System.out.println("Could not download file " + ex.getMessage());
    return false;
  }
}

Problem

I'm developing, in Java, an application that has to download from a server to client some very large files. So far I'm using the apache commons-net: ``` FileOutputStream out = new FileOutputStream(file); client.retrieveFile(filename, out); ``` The connection commonly fails before the client finishes downloading the file. I need a way to resume the download of the file from the point where the connection failed, without downloading the whole file again, is it possible?

Original source