Apache Commons Net FTP is uploading corrupted files

前端 未结 3 795
-上瘾入骨i
-上瘾入骨i 2020-12-06 02:13

I\'m trying to use Apache Commons Net for FTP file transfers.

Problem is files are intermittently arriving at the server corrupt. By \'corrupt\' I mean that WinRAR t

3条回答
  •  暗喜
    暗喜 (楼主)
    2020-12-06 02:52

    I had this problem despite specifying binary file type so I wrote code to validate the uploaded file via MD5 hashing:

    public void upload(String sourceFilePath) throws Exception
    {
        while (true)
        {
            // Upload
            File sourceFile = new File(sourceFilePath);
            String sourceFileHash = MD5Checksum.getMD5Checksum(sourceFilePath);
            String remoteFile = sourceFile.getName();
    
            try (InputStream inputStream = new FileInputStream(sourceFile))
            {
                boolean successful = ftpClient.storeFile(remoteFile, inputStream);
    
                if (!successful)
                {
                    throw new IllegalStateException("Upload of " + sourceFilePath + " failed!");
                }
            }
    
            // Download
            File temporaryFile = File.createTempFile("prefix", "suffix");
            try (OutputStream outputStream = new BufferedOutputStream(new FileOutputStream(temporaryFile)))
            {
                boolean successful = ftpClient.retrieveFile(remoteFile, outputStream);
    
                if (!successful)
                {
                    throw new IllegalStateException("Download of " + sourceFilePath + " failed!");
                }
            }
    
            String downloadFileHash = MD5Checksum.getMD5Checksum(temporaryFile.getAbsolutePath());
            Files.delete(temporaryFile.toPath());
    
            // Make sure the file hashes match
            if (sourceFileHash.equals(downloadFileHash))
            {
                break;
            }
        }
    }
    

    MD5Checksum.java:

    import java.io.*;
    import java.security.MessageDigest;
    
    public class MD5Checksum
    {
        private static byte[] createChecksum(String filename) throws Exception
        {
            try (InputStream fileInputStream = new FileInputStream(filename))
            {
                byte[] buffer = new byte[1024];
                MessageDigest complete = MessageDigest.getInstance("MD5");
                int numRead;
    
                do
                {
                    numRead = fileInputStream.read(buffer);
                    if (numRead > 0)
                    {
                        complete.update(buffer, 0, numRead);
                    }
                } while (numRead != -1);
    
                return complete.digest();
            }
        }
    
        public static String getMD5Checksum(String filename) throws Exception
        {
            byte[] checksum = createChecksum(filename);
            StringBuilder result = new StringBuilder();
    
            for (byte singleByte : checksum)
            {
                result.append(Integer.toString((singleByte & 0xff) + 0x100, 16).substring(1));
            }
    
            return result.toString();
        }
    }
    

    The MD5 code is taken from here.

提交回复
热议问题