Java - 传递url并获取其InputStream的实用程序方法

时间:2014-02-09 18:21:16

标签: java url inputstream

我想写一个像这样的实用功能

public static InputStream getInputStream(URL url) {...}

这样我就可以根据我的用法使用InputStream

例如

如果想要下载歌曲,那么我可以直接将InputStream中的字节写入文件而不转换字节 - >>字符串 - >>文件

OR

如果我想从url中读取一些文本,那么我可以将InputStream转换为String。

问题:

  1. 当我在调用函数中使用此InputStream时,我收到以下异常

    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)
    
  2. 让我们说即使我能够成功读取InputStream中的内容,如何关闭我在此实用程序函数中创建的HttpConnection?如果我在返回之前关闭它,那么InputStream将不起作用。如果我在从效用函数返回之前没有关闭它,那么连接将保持未闭合状态。

  3. 注意:我不想从实用程序函数返回byte []String,因为在某些情况下数据可能非常大,因为我无法将整个数据存储在内存中在对该数据进行操作之前。

    代码:

    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;
    }
    

    注意:我使用的是org.apache.http.impl.client.DefaultHttpClient

2 个答案:

答案 0 :(得分:3)

您可以返回自己的InputStream实现,该实现包装连接的InputStream并覆盖close方法。 FilterInputStream已完成大部分工作,因为它将操作委托给随附的InputStream

答案 1 :(得分:1)

你能做什么:

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();
}