0

Hi I am trying to connect FTP and read a file and generate md5 checksum value for that file, but I am facing Stream Closed error. Here is my code.

import java.io.FileInputStream;
import java.security.MessageDigest;
import java.util.Properties;
import java.io.InputStream;
import java.io.ByteArrayInputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import org.apache.commons.net.ftp.FTPClient;

MessageDigest digest = MessageDigest.getInstance("MD5");

FTPClient ftp=new FTPClient();
ftp.enterLocalPassiveMode();
ftp.connect("address");
ftp.login('username','password');
InputStream iStream=ftp.retrieveFileStream("path of the file");
BufferedInputStream bInf=new BufferedInputStream(iStream);
byte[] buffer = new byte[8192];    
int read = 0;
while ((read = bInf.read(buffer)) !=-1)
{
digest.update(buffer, 0, read);
};

byte[] md5sum = digest.digest();
BigInteger bigInt = new BigInteger(1, md5sum)
def x=bigInt.toString(16).padLeft(32,'0')

Kindly help me where I went wrong

tim_yates
  • 167,322
  • 27
  • 342
  • 338
Shashank Cool
  • 91
  • 2
  • 11

1 Answers1

1

I got it to work with the following code:

import java.security.MessageDigest
import org.apache.commons.net.ftp.FTPClient

MessageDigest digest = MessageDigest.getInstance("MD5")

String md5 = new FTPClient().with { ftp ->
    try {
        ftp.enterLocalPassiveMode()
        ftp.connect( address )
        ftp.login( username, password )
        ftp.retrieveFileStream( path ).with { ins ->
            if( ins == null ) {
                println "ERROR: $ftp.replyCode '${ftp.replyString.trim()}'"
            }
            else {
                try {
                    ins.eachByte( 8192 ) { buffer, nbytes ->
                        digest.update( buffer, 0, nbytes )
                    }
                    digest.digest().encodeHex().toString().padLeft( 32, '0' )
                }
                finally {
                    ins.close()
                }
            }
        }
    }
    finally {
        ftp.disconnect()
    }
}

(assuming you have variables defined for address, username, password and path)

tim_yates
  • 167,322
  • 27
  • 342
  • 338
  • It says Cannot invoke method close() on null object. It is going at eachByte( 8192 ) { buffer, nbytes -> digest.update( buffer, 0, nbytes ) – Shashank Cool Mar 12 '14 at 13:24
  • Don't understand the second part of you comment... Anyway, try that, I was more explicit with my `with` variable names. What version of Groovy? I tested that with `2.2.2` and `commons-net:commons-net:3.3` for `FTPClient`, and it works for me... – tim_yates Mar 12 '14 at 13:27
  • Actually retrieveFileStream is returning null – Shashank Cool Mar 12 '14 at 14:02
  • Maybe check the path exists? – tim_yates Mar 12 '14 at 14:05
  • yes the path exists It is throwing error Cannot invoke method close() on null object. – Shashank Cool Mar 12 '14 at 14:15
  • Is it a path to a valid object or is it a symbolic link? I know it's a dreadful response, but yet again _"it works on my machine"_ – tim_yates Mar 12 '14 at 14:24
  • :when I try to print digest.update( buffer, 0, nbytes ) .It prints value as null – Shashank Cool Mar 12 '14 at 14:26
  • Yes, because it didn't get an inputStream so wrote no bytes into the digest and crashed tying to close a null inputStream. As it says in [the documentation](http://commons.apache.org/proper/commons-net/apidocs/org/apache/commons/net/ftp/FTPClient.html#retrieveFileStream(java.lang.String)) _"Returns: An InputStream from which the remote file can be read. If the data connection cannot be opened (e.g., the file does not exist), null is returned (in which case you may check the reply code to determine the exact reason for failure)."_ – tim_yates Mar 12 '14 at 14:29
  • @ShashankCool Updated answer to catch null input stream and print the reply which should show why it was null – tim_yates Mar 12 '14 at 14:33
  • Could you please help me how to check the replycode in this program @tim_yates – Shashank Cool Mar 12 '14 at 14:38
  • @ShashankCool I have. See the answer – tim_yates Mar 12 '14 at 14:51
  • It is printing RROR: 200 '200 PORT command successful. Consider using PASV.' @tim_yates – Shashank Cool Mar 12 '14 at 15:03
  • What happens if you remove `ftp.enterLocalPassiveMode()`? – tim_yates Mar 12 '14 at 15:25
  • Your Code is correct but it is not working in my case @tim_yates – Shashank Cool Mar 12 '14 at 15:52
  • @ShashankCool [this seems to suggest](http://www.codejava.net/java-se/networking/ftp/java-ftp-file-download-tutorial-and-example#SampleCode) you need a call to `completePendingCommand` but I'm struggling to get it to work with my code... – tim_yates Mar 12 '14 at 15:55
  • Thank you for the help @tim_yates . Even I am unable to find the issue yet . It is throwing the same error Cannot invoke method close() on null object – Shashank Cool Mar 12 '14 at 16:05