在java中将inputstream转换为字节数组

wtlkbnrh  于 2021-09-13  发布在  Java
关注(0)|答案(30)|浏览(621)

我如何阅读整本书 InputStream 进入字节数组?

nhjlsmyf

nhjlsmyf16#

您可以使用ApacheCommonsIO来处理此任务和类似的任务。
这个 IOUtils 类型有一个静态方法来读取 InputStream 并返回一个 byte[] .

InputStream is;
byte[] bytes = IOUtils.toByteArray(is);

这在内部创建了一个 ByteArrayOutputStream 并将字节复制到输出,然后调用 toByteArray() . 它通过复制4KB块中的字节来处理大型文件。

dfddblmv

dfddblmv17#

java 9最终将为您提供一个很好的方法:

InputStream in = ...;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
in.transferTo( bos );
byte[] bytes = bos.toByteArray();
qcuzuvrc

qcuzuvrc18#

Input Stream is ...
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int next = in.read();
while (next > -1) {
    bos.write(next);
    next = in.read();
}
bos.flush();
byte[] result = bos.toByteArray();
bos.close();
v7pvogib

v7pvogib19#

@亚当斯基:你可以完全避免缓冲区。
从复制的代码http://www.exampledepot.com/egs/java.io/file2bytearray.html (是的,它非常冗长,但需要的内存大小只有另一种解决方案的一半。)

// Returns the contents of the file in a byte array.
public static byte[] getBytesFromFile(File file) throws IOException {
    InputStream is = new FileInputStream(file);

    // Get the size of the file
    long length = file.length();

    // You cannot create an array using a long type.
    // It needs to be an int type.
    // Before converting to an int type, check
    // to ensure that file is not larger than Integer.MAX_VALUE.
    if (length > Integer.MAX_VALUE) {
        // File is too large
    }

    // Create the byte array to hold the data
    byte[] bytes = new byte[(int)length];

    // Read in the bytes
    int offset = 0;
    int numRead = 0;
    while (offset < bytes.length
           && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) {
        offset += numRead;
    }

    // Ensure all the bytes have been read in
    if (offset < bytes.length) {
        throw new IOException("Could not completely read file "+file.getName());
    }

    // Close the input stream and return bytes
    is.close();
    return bytes;
}
5n0oy7gb

5n0oy7gb20#

ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
while (true) {
    int r = in.read(buffer);
    if (r == -1) break;
    out.write(buffer, 0, r);
}

byte[] ret = out.toByteArray();
rxztt3cl

rxztt3cl21#

如果不想使用apache commons io库,则此代码段取自sun.misc.ioutils类。它的速度几乎是使用bytebuffers的常见实现的两倍:

public static byte[] readFully(InputStream is, int length, boolean readAll)
        throws IOException {
    byte[] output = {};
    if (length == -1) length = Integer.MAX_VALUE;
    int pos = 0;
    while (pos < length) {
        int bytesToRead;
        if (pos >= output.length) { // Only expand when there's no room
            bytesToRead = Math.min(length - pos, output.length + 1024);
            if (output.length < pos + bytesToRead) {
                output = Arrays.copyOf(output, pos + bytesToRead);
            }
        } else {
            bytesToRead = output.length - pos;
        }
        int cc = is.read(output, pos, bytesToRead);
        if (cc < 0) {
            if (readAll && length != Integer.MAX_VALUE) {
                throw new EOFException("Detect premature EOF");
            } else {
                if (output.length != pos) {
                    output = Arrays.copyOf(output, pos);
                }
                break;
            }
        }
        pos += cc;
    }
    return output;
}
xghobddn

xghobddn22#

如果有人仍在寻找没有依赖关系的解决方案,并且您有一个文件。
数据输入流

byte[] data = new byte[(int) file.length()];
 DataInputStream dis = new DataInputStream(new FileInputStream(file));
 dis.readFully(data);
 dis.close();

bytearrayoutputstream

InputStream is = new FileInputStream(file);
 ByteArrayOutputStream buffer = new ByteArrayOutputStream();
 int nRead;
 byte[] data = new byte[(int) file.length()];
 while ((nRead = is.read(data, 0, data.length)) != -1) {
     buffer.write(data, 0, nRead);
 }

随机存取文件

RandomAccessFile raf = new RandomAccessFile(file, "r");
 byte[] data = new byte[(int) raf.length()];
 raf.readFully(data);
ukxgm1gy

ukxgm1gy23#

你真的需要图像作为一个整体吗 byte[] ? 你对未来有什么期待 byte[] -图像文件的完整内容,以图像文件的任何格式编码,或rgb像素值?
这里的其他答案向您展示了如何将文件读入 byte[] . 你的 byte[] 将包含文件的确切内容,您需要对其进行解码才能处理图像数据。
java读取(和写入)图像的标准api是imageio api,您可以在包中找到它 javax.imageio . 您只需一行代码即可从文件中读入图像:

BufferedImage image = ImageIO.read(new File("image.jpg"));

这会给你一个惊喜 BufferedImage ,而不是 byte[] . 要获取图像数据,可以调用 getRaster()BufferedImage . 这会给你一个惊喜 Raster 对象,该对象具有访问像素数据的方法(它有多个 getPixel() / getPixels() 方法)。
请查阅api文档以了解更多信息 javax.imageio.ImageIO , java.awt.image.BufferedImage , java.awt.image.Raster
默认情况下,imageio支持多种图像格式:jpeg、png、bmp、wbmp和gif。可以添加对更多格式的支持(您需要一个实现imageio服务提供程序接口的插件)。
另请参见以下教程:使用图像

5tmbdcev

5tmbdcev24#

安全解决方案(具有 close 流(正确):
java 9+:

final byte[] bytes;
 try (inputStream) {
     bytes = inputStream.readAllBytes();
 }

java 8:

public static byte[] readAllBytes(InputStream inputStream) throws IOException {
     final int bufLen = 4 * 0x400; // 4KB
     byte[] buf = new byte[bufLen];
     int readLen;
     IOException exception = null;

     try {
         try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
             while ((readLen = inputStream.read(buf, 0, bufLen)) != -1)
                 outputStream.write(buf, 0, readLen);

             return outputStream.toByteArray();
         }
     } catch (IOException e) {
         exception = e;
         throw e;
     } finally {
         if (exception == null) inputStream.close();
         else try {
             inputStream.close();
         } catch (IOException e) {
             exception.addSuppressed(e);
         }
     }
 }

kotlin(当无法访问java 9+时):

@Throws(IOException::class)
 fun InputStream.readAllBytes(): ByteArray {
     val bufLen = 4 * 0x400 // 4KB
     val buf = ByteArray(bufLen)
     var readLen: Int = 0

     ByteArrayOutputStream().use { o ->
         this.use { i ->
             while (i.read(buf, 0, bufLen).also { readLen = it } != -1)
                 o.write(buf, 0, readLen)
         }

         return o.toByteArray()
     }
 }

避免嵌套 use 看这里。
scala(当java 9+不可访问时)(作者@joan。thx):

def readAllBytes(inputStream: InputStream): Array[Byte] =
  Stream.continually(inputStream.read).takeWhile(_ != -1).map(_.toByte).toArray
7lrncoxx

7lrncoxx25#

public static byte[] getBytesFromInputStream(InputStream is) throws IOException {
    ByteArrayOutputStream os = new ByteArrayOutputStream(); 
    byte[] buffer = new byte[0xFFFF];
    for (int len = is.read(buffer); len != -1; len = is.read(buffer)) { 
        os.write(buffer, 0, len);
    }
    return os.toByteArray();
}
6mzjoqzu

6mzjoqzu26#

一如既往,spring框架(自3.2.2以来的spring核心)也为您提供了一些东西: StreamUtils.copyToByteArray()

agxfikkp

agxfikkp27#

如果你碰巧使用谷歌Guava,它将与使用谷歌Guava一样简单 ByteStreams :

byte[] bytes = ByteStreams.toByteArray(inputStream);
xe55xuns

xe55xuns28#

使用香草java的 DataInputStream 及其 readFully 方法(至少从java 1.4开始存在):

...
byte[] bytes = new byte[(int) file.length()];
DataInputStream dis = new DataInputStream(new FileInputStream(file));
dis.readFully(bytes);
...

这个方法还有其他一些风格,但我一直在这个用例中使用它。

fkvaft9z

fkvaft9z29#

最后,二十年后,由于java 9,有了一个不需要第三方库的简单解决方案:

InputStream is;
…
byte[] array = is.readAllBytes();

还要注意方便的方法 readNBytes(byte[] b, int off, int len)transferTo(OutputStream) 解决经常性需要。

gk7wooem

gk7wooem30#

您需要从数据库中读取每个字节 InputStream 然后写给一个 ByteArrayOutputStream .
然后,您可以通过调用 toByteArray() :

InputStream is = ...
ByteArrayOutputStream buffer = new ByteArrayOutputStream();

int nRead;
byte[] data = new byte[16384];

while ((nRead = is.read(data, 0, data.length)) != -1) {
  buffer.write(data, 0, nRead);
}

return buffer.toByteArray();

相关问题