6

I'm attempting to retrieve a file from an FTP server, using this code.

private class FtpTask extends AsyncTask<Void, Void, Long> {
    protected Long doInBackground(Void... args) {

        FTPClient FtpClient = new FTPClient();
        int reply;

        try {
            FtpClient.connect(ftpServer);
            FtpClient.login(ftpUser, ftpPass);

            reply = FtpClient.getReplyCode();

            if (FTPReply.isPositiveCompletion(reply)) {
                String remoteFileName = "ACPlus.ZIP";
                String localFile = context.getFilesDir() + "/ACPLUS.ZIP";

                // Delete local file first
                File file = new File(localFile);
                if(file.exists()) {
                    file.delete();
                }

                FtpClient.changeWorkingDirectory("/" + ftpFolder);
                FtpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
                FtpClient.enterLocalPassiveMode();

                OutputStream outputStream = null;

                boolean success = false;
                try {
                    outputStream = new BufferedOutputStream(new FileOutputStream(localFile));
                    success = FtpClient.retrieveFile(remoteFileName, outputStream);

                    reply = FtpClient.getReplyCode();
                }
                finally {
                    if (outputStream != null) {
                        outputStream.close();
                    }
                }

                bConnected = success;
            }
            else
            {
                bConnected = false;
            }
        }
        catch (Exception ex) {
            return null;
        }

        return null;
    }

    protected void onPostExecute(Long result) {
        super.onPostExecute(result);

        if (bConnected == true) {
            // Extract local file
            File file = new File(context.getFilesDir() + "/ACPLUS.ZIP");
            if(file.exists()) {

            }
        }
        else
        {
            AlertDialog.Builder msg = new AlertDialog.Builder(context);
            msg.setTitle("Error");
            msg.setMessage("Connection could not be established!");
            msg.setPositiveButton("OK", new DialogInterface.OnClickListener() {
              @Override
                public void onClick(DialogInterface dialog, int which) {
                    // Do nothing
                }
            });

            AlertDialog dialog = msg.create();
            dialog.show();
        }
    }

As a test, I stepped through the code and after I reached had stepped through

// Delete local file first
   File file = new File(localFile);
   if(file.exists()) {
        file.delete();
    }

I stopped debugging, so I knew that the file had been deleted. Then, I started stepping through again; this time it missed out file.delete(); as the if statement was false, so that proved that the delete file had been completed successfully.

However, when I continued to step through, when I reached the line success = FtpClient.retrieveFile(remoteFileName, outputStream);, success had a value of false, which meant my onPostExecute didn't go through the correct code.

However, when debugging it again, this time it did go through the if statement and deleted the local file, suggesting it had in fact downloaded, despite success = false suggesting otherwise.

Have I misunderstood something, or is this the usual behaviour?

vincrichaud
  • 2,218
  • 17
  • 34
David
  • 2,298
  • 6
  • 22
  • 56
  • 1
    If FtpClient.retrieveFile returns false, there should be something wrong, such as network jitter caused network transfer interrupted, suggest to add log to print exception message in your catch block, you cannot just return null which is same with correct behavior, or check the file integrity after downloading. – Rong Zhao May 15 '19 at 07:07
  • @RongZhao how would I check the file integrity? – David May 15 '19 at 08:55
  • If you can control the FTP server, you can calculate md5sum of the file on server and calculate md5sum of downloaded file, compare them should be same. But before this, I think you can try to print some logs in your catch block to see if there is any abnormal things happen, from the code logic, if there is exception, your code will not set bConnected = True, just finish the async task... – Rong Zhao May 16 '19 at 09:06

0 Answers0