java.net.URL read stream to byte[]

后端 未结 8 433
失恋的感觉
失恋的感觉 2020-11-29 03:11

I`m trying to read an image from an URL (with the java package java.net.URL) to a byte[]. \"Everything\" works fine, except that the content isnt being ent

相关标签:
8条回答
  • 2020-11-29 03:45

    I am very surprised that nobody here has mentioned the problem of connection and read timeout. It could happen (especially on Android and/or with some crappy network connectivity) that the request will hang and wait forever.

    The following code (which also uses Apache IO Commons) takes this into account, and waits max. 5 seconds until it fails:

    public static byte[] downloadFile(URL url)
    {
        try {
            URLConnection conn = url.openConnection();
            conn.setConnectTimeout(5000);
            conn.setReadTimeout(5000);
            conn.connect(); 
    
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            IOUtils.copy(conn.getInputStream(), baos);
    
            return baos.toByteArray();
        }
        catch (IOException e)
        {
            // Log error and return null, some default or throw a runtime exception
        }
    }
    
    0 讨论(0)
  • 2020-11-29 03:49

    The content length is just a HTTP header. You cannot trust it. Just read everything you can from the stream.

    Available is definitely wrong. It's just the number of bytes that can be read without blocking.

    Another issue is your resource handling. Closing the stream has to happen in any case. try/catch/finally will do that.

    0 讨论(0)
  • 2020-11-29 03:53

    There's no guarantee that the content length you're provided is actually correct. Try something akin to the following:

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    InputStream is = null;
    try {
      is = url.openStream ();
      byte[] byteChunk = new byte[4096]; // Or whatever size you want to read in at a time.
      int n;
    
      while ( (n = is.read(byteChunk)) > 0 ) {
        baos.write(byteChunk, 0, n);
      }
    }
    catch (IOException e) {
      System.err.printf ("Failed while reading bytes from %s: %s", url.toExternalForm(), e.getMessage());
      e.printStackTrace ();
      // Perform any other exception handling that's appropriate.
    }
    finally {
      if (is != null) { is.close(); }
    }
    

    You'll then have the image data in baos, from which you can get a byte array by calling baos.toByteArray().

    This code is untested (I just wrote it in the answer box), but it's a reasonably close approximation to what I think you're after.

    0 讨论(0)
  • 2020-11-29 04:02

    It's important to specify timeouts, especially when the server takes to respond. With pure Java, without using any dependency:

    public static byte[] copyURLToByteArray(final String urlStr,
            final int connectionTimeout, final int readTimeout) 
                    throws IOException {
        final URL url = new URL(urlStr);
        final URLConnection connection = url.openConnection();
        connection.setConnectTimeout(connectionTimeout);
        connection.setReadTimeout(readTimeout);
        try (InputStream input = connection.getInputStream();
                ByteArrayOutputStream output = new ByteArrayOutputStream()) {
            final byte[] buffer = new byte[8192];
            for (int count; (count = input.read(buffer)) > 0;) {
                output.write(buffer, 0, count);
            }
            return output.toByteArray();
        }
    }
    

    Using dependencies, e.g., HC Fluent:

    public byte[] copyURLToByteArray(final String urlStr,
            final int connectionTimeout, final int readTimeout)
                    throws IOException {
        return Request.Get(urlStr)
                .connectTimeout(connectionTimeout)
                .socketTimeout(readTimeout)
                .execute()
                .returnContent()
                .asBytes();
    }
    
    0 讨论(0)
  • 2020-11-29 04:03

    Just extending Barnards's answer with commons-io. Separate answer because I can not format code in comments.

    InputStream is = null;
    try {
      is = url.openStream ();
      byte[] imageBytes = IOUtils.toByteArray(is);
    }
    catch (IOException e) {
      System.err.printf ("Failed while reading bytes from %s: %s", url.toExternalForm(), e.getMessage());
      e.printStackTrace ();
      // Perform any other exception handling that's appropriate.
    }
    finally {
      if (is != null) { is.close(); }
    }
    

    http://commons.apache.org/io/api-1.4/org/apache/commons/io/IOUtils.html#toByteArray(java.io.InputStream)

    0 讨论(0)
  • 2020-11-29 04:08
    byte[] b = IOUtils.toByteArray((new URL( )).openStream()); //idiom
    

    Note however, that stream is not closed in the above example.

    if you want a (76-character) chunk (using commons codec)...

    byte[] b = Base64.encodeBase64(IOUtils.toByteArray((new URL( )).openStream()), true);
    
    0 讨论(0)
提交回复
热议问题