Question

I'm trying to download a JAR file from a secure HTTP server. I can download the file without errors but when I try to run the jar file Windows reports an invalid or corrupt file. Because there are no errors I can't tell where the problem lies, I assume it's the fact that it's an HTTPS server though. I know that there is data missing though because the file should be 3.8MB but when I finish downloading it's only 27KB.

Download method is:

EDIT: New Code with loop inserted but it still only gives me 27KB file.

public static boolean downloadFile(String fileLocation, String urlLocation) {
    try {
        System.setProperty("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol");
        Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
        int i;
        URL url = new URL(urlLocation);
        URLConnection conn= url.openConnection();
        File f = new File(fileLocation);
        BufferedInputStream bis = new BufferedInputStream(conn.getInputStream());
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(f.getName()));
        while ((i = bis.read()) != -1) {
            bos.write(i);
        }
        bos.flush();
        bos.close();
        return true;
    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return false;
}
Was it helpful?

Solution

The javadoc for FileChannel.transferFrom says this:

"An attempt is made to read up to count bytes from the source channel and write them to this channel's file starting at the given position. An invocation of this method may or may not transfer all of the requested bytes; whether or not it does so depends upon the natures and states of the channels. Fewer than the requested number of bytes will be transferred if the source channel has fewer than count bytes remaining, or if the source channel is non-blocking and has fewer than count bytes immediately available in its input buffer."

In this case, the source channel is a non-blocking channel, and therefore the transferFrom method is not guaranteed to transfer the entire content in one go.

As @EJP says, you need to put the transferFrom call into a loop, etcetera.

But I think you would be better off using the InputStream and OutputStream APIs directly, reading into and writing out of a byte[] ... in a loop.

OTHER TIPS

You need to call transferFrom() in a loop. It isn't guaranteed to perform the entire transfer. Its return value tells you how many bytes it transferred.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top