Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

InputStream won't close, or takes forever to

I'm attempting to download an external mp3 into internal storage. However, the files I'm attempting to download are big, so I'm trying to download them in 1MB chunks so that you can begin playing them while the rest is downloaded. Here's my stream code:

    InputStream is = null;
    OutputStream os = null;

    try {
        HttpClient client = new DefaultHttpClient();
        HttpGet get = new HttpGet( url );
        HttpResponse response = client.execute( get );

        MyLog.d( "Connection established" );

        byte[] buffer = new byte[8192];
        is = new BufferedInputStream( response.getEntity().getContent(), buffer.length );
        os = openFileOutput( filename, MODE_PRIVATE );

        int size;
        int totalSize = 0;

        while (( size = is.read( buffer ) ) != -1 && totalSize < 1048576) {
            os.write( buffer, 0, size );
            totalSize += size;
        }

        MyLog.d( "Finished downloading mix - " + totalSize + " bytes" );
    }
    catch (ClientProtocolException e) {
        e.printStackTrace();
    }
    catch (IOException e) {
        e.printStackTrace();
    }
    finally {
        if ( os != null ) {
            try {
                os.flush();
                os.close();
            }
            catch (IOException e) {
                MyLog.e( "Failed to close output stream." );
            }
        }
        if ( is != null ) {
            try {
                is.close();
            }
            catch (IOException e) {
                MyLog.e( "Failed to close input stream." );
            }
        }
    }

It downloads the file fine, but when it gets to is.close() in the finally statement, it hangs. If I wait a really long time it'll eventually close. It seems like it's still downloading the rest of the file. How do I avoid this and close the stream immediately?

like image 850
Jason Robinson Avatar asked Apr 24 '11 23:04

Jason Robinson


1 Answers

With HTTP, You normally still have to read (and throw away) the whole rest of the response stream - you cannot just close. The entire stream must be consumed. I am not sure if Android's httpclient is based on commons httpclient 3 or 4 - with 4 you can use HttpUriRequest#abort() to end early. Not sure if 3 has such an option

Edit: Looked it up and it looks like httpclient 3 , and you can do httpget.abort()

like image 160
MJB Avatar answered Sep 21 '22 04:09

MJB