我该如何将整个InputStream
读入字节数组中?
我该如何将整个InputStream
读入字节数组中?
您可以使用Apache Commons IO来处理这个和类似的任务。
IOUtils
类型有一个静态方法,用于读取InputStream
并返回byte[]
。
InputStream is;
byte[] bytes = IOUtils.toByteArray(is);
它在内部创建一个ByteArrayOutputStream
并将字节复制到输出中,然后调用toByteArray()
。它通过按块大小为4KiB复制字节来处理大文件。
FastArrayList
或他们的软/弱引用映射,然后回来告诉我这个库有多"经过充分测试"。它是一堆垃圾。 - oxbow_lakesInputStream is;
byte[] filedata=ByteStreams.toByteArray(is);
- michaelok你需要从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();
终于,在二十年后,由于 Java 9 的帮助,现在有一个简单的解决方案,无需使用第三方库:
InputStream is;
…
byte[] array = is.readAllBytes();
注意还有方便的方法readNBytes(byte[] b, int off, int len)
和transferTo(OutputStream)
用于解决重复需求。
InputStream
是否覆盖了readAllBytes()
或readNBytes
方法? - Holger使用纯Java的 DataInputStream
和它的 readFully
方法(至少从 Java 1.4 开始存在):
...
byte[] bytes = new byte[(int) file.length()];
DataInputStream dis = new DataInputStream(new FileInputStream(file));
dis.readFully(bytes);
...
还有其他一些方法,但我经常用这种方法来处理这种情况。
InputStream.read
更好。 - Logan Pickup如果你碰巧使用Google Guava,那么使用ByteStreams
就像呼吸一样简单:
byte[] bytes = ByteStreams.toByteArray(inputStream);
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提供。感谢):
def readAllBytes(inputStream: InputStream): Array[Byte] =
Stream.continually(inputStream.read).takeWhile(_ != -1).map(_.toByte).toArray
ByteArrayOutputStream
?这是不正确的做法,并且会让阅读代码的人误以为需要关闭它,尽管关闭ByteArrayOutputStream
并没有任何作用。实际上,声明ByteArrayOutputStream
的整个try
块都应该重写。那里根本不需要一个try
块... - Kröw一如既往,也Spring框架(自3.2.2起的spring-core)为你提供了以下方法:StreamUtils.copyToByteArray()
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();
}
如果有人仍在寻找一种无依赖性的解决方案,而且您有一个文件,则可以考虑使用以下代码:
DataInputStream
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);
你真的需要将图像作为byte[]
吗? 你期望在byte[]
中得到什么 - 图像文件的完整内容,以任何格式编码的,还是RGB像素值?其他答案展示了如何将文件读入byte[]
。你的byte[]
将包含完整的文件内容,你需要解码才能对图像数据进行处理。
Java的标准API用于读取(和写入)图像是ImageIO API,在javax.imageio
包中。你可以使用一行代码从文件中读取图像:
BufferedImage image = ImageIO.read(new File("image.jpg"));
这将给你一个BufferedImage
,而不是一个byte[]
。要访问图像数据,你可以在BufferedImage
上调用getRaster()
。这将给你一个Raster
对象,它有许多方法来访问像素数据(包括几个getPixel()
/getPixels()
方法)。javax.imageio.ImageIO
、java.awt.image.BufferedImage
、java.awt.image.Raster
等API文档。