Search code examples
javaftpfile-transfer

Files are getting corrupted when download using ftp in java


Files are getting corrupted when I am trying to pull a compressed files. Here is the code I have used. I am not able to understand what I am going wrong. The format of files is .zip and inside it has XML files. After downloading it from remote server,XML files tags are changed and looks corrupted.

public Boolean pullConfirmationsFTP(String host, String sftpUserName, String sftpPwd,
      String sftpPort, String fromConfirmationDirectory, String archiveConfirmationDirectory,
      String toDirectory) {
    try {

      // new ftp client
      FTPClient ftp = new FTPClient();
      // try to connect
      ftp.connect(host);
      // login to server
      if (!ftp.login(sftpUserName, sftpPwd)) {
        ftp.logout();
        LOG4J.error("Authentication failed");
      }
      int reply = ftp.getReplyCode();
      // FTPReply stores a set of constants for FTP reply codes.
      if (!FTPReply.isPositiveCompletion(reply)) {
        ftp.disconnect();
      }

      // enter passive mode
      ftp.enterLocalPassiveMode();

      // get system name
      // System.out.println("Remote system is " + ftp.getSystemType());
      // change current directory
      ftp.changeWorkingDirectory(fromConfirmationDirectory);
      System.out.println("Current directory is " + ftp.printWorkingDirectory());

      // get list of filenames
      FTPFile[] ftpFiles = ftp.listFiles();

      if (ftpFiles != null && ftpFiles.length > 0) {
        // loop thru files
        for (FTPFile file : ftpFiles) {
          try{
          if (!file.isFile()) {
            continue;
          }
          LOG4J.error("File is " + file.getName());
          // get output stream
          OutputStream output;
          output = new FileOutputStream(toDirectory + file.getName());
          // get the file from the remote system
          ftp.retrieveFile(file.getName(), output);

          // close output stream
          output.close();

          // delete the file
          ftp.deleteFile(file.getName());
          }
          catch(Exception e)
          {
            LOG4J.error("Error in pushing file : ",e);
          }
        }
      }

      ftp.logout();
      ftp.disconnect();
    } catch (Exception ex) {
      ex.printStackTrace();
      LOG4J.error(ex);
    }

    return true;
  }

Solution

  • You didn't say which FTPClient you use, but I'm guessing it is from apache commons. Documentation for FTPClient says:

    The default settings for FTPClient are for it to use FTP.ASCII_FILE_TYPE , FTP.NON_PRINT_TEXT_FORMAT , FTP.STREAM_TRANSFER_MODE , and FTP.FILE_STRUCTURE . The only file types directly supported are FTP.ASCII_FILE_TYPE and FTP.BINARY_FILE_TYPE

    As the zip-file is a binary file you have to add

    ftp.setFileType(FTP.BINARY_FILE_TYPE);
    

    API: FTPClient.setFileType