Reputation: 34745
I wanted to write a Utility function something like this
public static InputStream getInputStream(URL url) {...}
so that I can use that InputStream
according to my usage.
e.g.
If want to download a song, then I can directly write bytes from the InputStream to a file without converting bytes ->> String -->> file
OR
If I want to read some text from the url, then I can convert the InputStream to String.
Problem:
When I am using this InputStream in my caller function, I am getting the following exception
java.net.SocketException: Socket closed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:150)
at java.net.SocketInputStream.read(SocketInputStream.java:121)
at org.apache.http.impl.io.AbstractSessionInputBuffer.read(AbstractSessionInputBuffer.java:204)
at org.apache.http.impl.io.ContentLengthInputStream.read(ContentLengthInputStream.java:182)
at org.apache.http.conn.EofSensorInputStream.read(EofSensorInputStream.java:138)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:283)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:325)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:177)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.Reader.read(Reader.java:140)
at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:2001)
at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1980)
at org.apache.commons.io.IOUtils.copy(IOUtils.java:1957)
at org.apache.commons.io.IOUtils.copy(IOUtils.java:1907)
at org.apache.commons.io.IOUtils.toString(IOUtils.java:778)
at org.apache.commons.io.IOUtils.toString(IOUtils.java:803)
at hungama.HungamaContentDownloader.downloadContent(HungamaContentDownloader.java:87)
at hungama.HungamaContentDownloader.main(HungamaContentDownloader.java:46)
Let's say even If I am able successfully read the content from the InputStream, How can I close the HttpConnection
that I created inside this utility function? If I close it before returning, then the InputStream won't work. And If I don't close it before returning from the utility function, then the connection will remain unclosed.
Note: I don't want to return byte []
or String
from the utility function because in some cases the data might be very large because of which I can't store the whole data in memory before operating on that data.
Code:
public static InputStream getRemoteHttpResource(String url, String username, String password, int timeout) {
if(url == null)
return null;
DefaultHttpClient client = null;
HttpGet request = null;
try {
client = new DefaultHttpClient();
client.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, timeout);
request = new HttpGet(url);
request.setHeader("Accept-Language", "en-US,en;q=0.8");
HttpResponse response = client.execute(request);
StatusLine statusLine = response.getStatusLine();
if (statusLine.getStatusCode() == 200)
return response.getEntity().getContent();
else
logger.warn("Error response : " + statusLine + ". For : " + url + ". Response: " + response);
}
catch (Exception e) {
logger.error(e.getMessage(), e);
} finally {
if(request != null)
request.releaseConnection();
if (client != null)
client.getConnectionManager().shutdown();
}
return null;
}
Note: I am using org.apache.http.impl.client.DefaultHttpClient
Upvotes: 1
Views: 1591
Reputation: 43738
You could return your own implementation of InputStream
that wraps the InputStream of the connection and override the close
method. A FilterInputStream
would already do most of the job, as it delegates the operations to the enclosed InputStream
.
Upvotes: 3
Reputation: 11440
What you could do:
void pipRemoteHttpResource(String url, String username, String password, int timeout, OutputStream out) {
.. same code ..
if (statusLine.getStatusCode() == 200)
pipeStreams(response.getEntity().getContent(), out);
.. same code ..
}
// writes input to output
public static void pipeStreams(java.io.InputStream source, java.io.OutputStream destination) throws IOException {
// 16kb buffer
byte [] buffer = new byte[16 * 1024];
int read = 0;
while((read=source.read(buffer)) != -1) {
destination.write(buffer, 0, read);
}
destination.flush();
destination.close();
source.close();
}
Upvotes: 1