steam1234322
steam1234322

Reputation: 63

Files that I download from an FTP server do not have the same length as the files on the server

I am downloading files from a server using FTPClient in Java. When the file is downloaded, I would like to check it's integrity and then delete it. I am doing this by comparing the size of both the downloaded file in bytes, and the file on the server in bytes, however the results are not as expected.

Below is an extract from my transfer directory:

for (int i = 0; i <= insideDirectory.length - 1; i++) {
                    FTPFile transferFile = insideDirectory[i];
                    LOGGER.info("Passing file" + folder.getName() + "/" + transferFile.getName());

                    File downloadFile = new File("/users/home/example" + i + ".mp4");
                    OutputStream outputStream2 = new BufferedOutputStream(new FileOutputStream(downloadFile));
                    System.out.println(transferFile.getSize());
                    ftpClient.enterLocalPassiveMode();
                    ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
                    InputStream inputStream = ftpClient
                            .retrieveFileStream(folder.getName() + "/" + transferFile.getName());
                    byte[] bytesArray = new byte[4096];
                    int bytesRead = -1;
                    while ((bytesRead = inputStream.read(bytesArray)) != -1) {
                        outputStream2.write(bytesArray, 0, bytesRead);
                    }

                    Boolean success = ftpClient.completePendingCommand();
                    if (success) {
                        System.out.println("File #" + i + " has been downloaded successfully.");
                        checkIfExists(downloadFile, transferFile);
                    }

Below is my checkIfExists method

public void checkIfExists(File downloadedFile, FTPFile remoteFileToDelete) {
    Long downloadedLength = downloadedFile.length();
    Long remoteLength = remoteFileToDelete.getSize();
    if (downloadedFile.length() == remoteFileToDelete.getSize()) {
        LOGGER.info(downloadedLength + "exists and is the same length as " + remoteLength + ". Let's delete");
    } else {
        LOGGER.info(downloadedLength + "is not the same length as " + remoteLength + ". Let's not delete");
    }
}

Here is the output after running the loop twice, as you can see, the size of the downloaded file can vary:

     File #0 has been downloaded successfully.
     INFO: 7596008is not the same length as 7600840. Let's not delete
     File #1 has been downloaded successfully.
     INFO: 6873664is not the same length as 6878544. Let's not delete
     File #2 has been downloaded successfully.
     INFO: 7558112is not the same length as 7564744. Let's not delete
     File #3 has been downloaded successfully.
     INFO: 8662336is not the same length as 8665108. Let's not delete

     File #0 has been downloaded successfully.
     INFO: 7594312is not the same length as 7600840. Let's not delete
     File #1 has been downloaded successfully.
     INFO: 6870392is not the same length as 6878544. Let's not delete
     File #2 has been downloaded successfully.
     INFO: 7559184is not the same length as 7564744. Let's not delete
     File #3 has been downloaded successfully.
     INFO: 8660888is not the same length as 8665108. Let's not delete

Upvotes: 1

Views: 867

Answers (1)

Alnitak
Alnitak

Reputation: 339947

.close() your BufferedOutputStream before you attempt to measure the size of the written file.

Without the .close() there's no guarantee (indeed quite the opposite) that all of the data that you have written to the stream will actually have been written to the underlying file that you access via the File object.

Upvotes: 3

Related Questions