KMH
KMH

Reputation: 95

URLConnection inputStream not being read fully

I wrote the following code for downloading some files from a server but the problem is that this code isn't reading the complete response (inputStream). File size is 7.5 MB while I am getting 5.5 MB each time and of course adobe reader complains that file is damaged. Here is the code

import java.net.URLConnection;
public class Downloader {
URL url;
public Downloader(){
    try {

        url = new URL("https://d396qusza40orc.cloudfront.net/algs4partI/slides%2F13StacksAndQueues.pdf");
        FileOutputStream outStream;
        ObjectOutputStream oStream;
        try {
            URLConnection con = url.openConnection();
            InputStream inStream = con.getInputStream();
            outStream = new FileOutputStream("data.pdf");
            oStream = new ObjectOutputStream(outStream);
            int bytesRead;
            int totalBytesRead = 0;
            byte[] buffer = new byte[100000];
            while((bytesRead = inStream.read(buffer)) > 0){

                //outStream.write(buffer, 0 , bytesRead);
                oStream.write(buffer, 0, bytesRead);
                buffer = new byte[100000];
                totalBytesRead += bytesRead;
            }
            System.out.println("Total Bytes read are = " + totalBytesRead);
            oStream.close();
            outStream.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    } catch (MalformedURLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}
public static void main(String[] args){
    Downloader d = new Downloader();
}

}

Any ideas what I am doing wrong here? Thanks in advance.

Upvotes: 2

Views: 3067

Answers (3)

Sotirios Delimanolis
Sotirios Delimanolis

Reputation: 279870

You don't want to be using ObjectOutputStream when you aren't serializing java objects.

Un-comment the line

//outStream.write(buffer, 0 , bytesRead);

and remove

oStream.write(buffer, 0, bytesRead);

So:

while((bytesRead = inStream.read(buffer)) > 0){

    outStream.write(buffer, 0 , bytesRead);           
    buffer = new byte[100000]; // this line is useless
    totalBytesRead += bytesRead;
}

Get rid of the ObjectOutputStream altogether. Your file is 5.25 MB (5,511,685 bytes) long, not 7.5 MB.

Upvotes: 1

Stephen C
Stephen C

Reputation: 718658

The problem is that you are using ObjectOutputStream. This encodes the output in the Java Object Serialization format, which is not what the PDF reader expects / requires.

Use a plain FileOutputStream and it should work.

Upvotes: 0

AlexR
AlexR

Reputation: 115328

InputStream that you get from URL connection does not guarantee that all bytes arrive at once. They are transfered over network, so your reading speed may be higher than your network. Method read() returns number of bytes that have been read at current execution of the method. If it returns 0 the information is probably not available at the moment but will be available later.

Method read() returns -1 to indicate end of stream. Bottom line: change > 0 in your if statement to >= 0.

Upvotes: 1

Related Questions