java.net.URL读取流到byte []

tim*_*ner 40 java url image bytearray

我试图将URL(使用java包java.net.URL)中的图像读取 到byte []."Everything"工作正常,除了内容不是从流中被读取(图像损坏,它不包含所有图像数据)...字节数组被保存在数据库(BLOB)中.我真的不知道正确的方法是什么,也许你可以给我一个提示:)

这是我的第一种方法(代码格式化,删除了不必要的信息......):

URL u = new URL("http://localhost:8080/images/anImage.jpg");
int contentLength = u.openConnection().getContentLength();
Inputstream openStream = u.openStream();
byte[] binaryData = new byte[contentLength];
openStream.read(binaryData);
openStream.close();
Run Code Online (Sandbox Code Playgroud)

我的第二个方法是这个(因为你会看到内容长度是另一种方式):

URL u = new URL(content);
openStream = u.openStream();
int contentLength = openStream.available();
byte[] binaryData = new byte[contentLength];
openStream.read(binaryData);
openStream.close();
Run Code Online (Sandbox Code Playgroud)

这两个代码都会导致图像损坏...我已经从stackoverflow中读到了这篇文章

RTB*_*ard 58

我们无法保证您提供的内容长度实际上是正确的.尝试类似于以下内容:

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(); }
}
Run Code Online (Sandbox Code Playgroud)

然后,您将拥有图像数据baos,通过调用可以从中获取字节数组baos.toByteArray().

这段代码是未经测试的(我只是在答案框中写了它),但它与我认为你所追求的相当接近.

  • 请不要写一个空的catch-block,即使在一个例子中也是如此!至少放置`e.printStackTrace()`!示例倾向于成为生产代码,我们都必须在以后使用它. (37认同)
  • 你是绝对正确的; 感谢您指出了这一点.我在示例中添加了更有意义的异常处理. (3认同)

Adi*_*Adi 27

只是用commons-io扩展Barnards的答案.单独回答因为我无法在评论中格式化代码.

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(); }
}
Run Code Online (Sandbox Code Playgroud)

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


Ron*_*ter 20

这是一个干净的解决方案:

private byte[] downloadUrl(URL toDownload) {
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

    try {
        byte[] chunk = new byte[4096];
        int bytesRead;
        InputStream stream = toDownload.openStream();

        while ((bytesRead = stream.read(chunk)) > 0) {
            outputStream.write(chunk, 0, bytesRead);
        }

    } catch (IOException e) {
        e.printStackTrace();
        return null;
    }

    return outputStream.toByteArray();
}
Run Code Online (Sandbox Code Playgroud)

  • 不要忘记在'stream'上调用close方法来释放使用过的资源. (7认同)

ala*_*ter 15

使用 commons-io IOUtils.toByteArray(URL)

String url = "http://localhost:8080/images/anImage.jpg";
byte[] fileContent = IOUtils.toByteArray(new URL(url));
Run Code Online (Sandbox Code Playgroud)

Maven 依赖:

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.6</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)


小智 11

byte[] b = IOUtils.toByteArray((new URL( )).openStream()); //idiom
Run Code Online (Sandbox Code Playgroud)

但请注意,在上面的示例中未关闭该流.

如果你想要一个(76个字符)块(使用commons编解码器)......

byte[] b = Base64.encodeBase64(IOUtils.toByteArray((new URL( )).openStream()), true);
Run Code Online (Sandbox Code Playgroud)

  • -1表示格式不正确,有点亵渎. (6认同)

Num*_*our 10

我很惊讶这里没有人提到连接和读取超时的问题.它可能会发生(特别是在Android和/或一些糟糕的网络连接上)请求将挂起并永远等待.

以下代码(也使用Apache IO Commons)将此考虑在内,并等待最大值.失败5秒钟:

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
    }
}
Run Code Online (Sandbox Code Playgroud)