如何将整个输入流读到字节数组?
当前回答
/*InputStream class_InputStream = null;
I am reading class from DB
class_InputStream = rs.getBinaryStream(1);
Your Input stream could be from any source
*/
int thisLine;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
while ((thisLine = class_InputStream.read()) != -1) {
bos.write(thisLine);
}
bos.flush();
byte [] yourBytes = bos.toByteArray();
/*Don't forget in the finally block to close ByteArrayOutputStream & InputStream
In my case the IS is from resultset so just closing the rs will do it*/
if (bos != null){
bos.close();
}
其他回答
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();
}
和往常一样,Spring框架(Spring core从3.2.2开始)也为你提供了一些东西:
下面的代码
public static byte[] serializeObj(Object obj) throws IOException {
ByteArrayOutputStream baOStream = new ByteArrayOutputStream();
ObjectOutputStream objOStream = new ObjectOutputStream(baOStream);
objOStream.writeObject(obj);
objOStream.flush();
objOStream.close();
return baOStream.toByteArray();
}
OR
BufferedImage img = ...
ByteArrayOutputStream baos = new ByteArrayOutputStream(1000);
ImageIO.write(img, "jpeg", baos);
baos.flush();
byte[] result = baos.toByteArray();
baos.close();
Kotlin中的解决方案(当然也可以在Java中工作),其中包括当你知道大小时的两种情况:
fun InputStream.readBytesWithSize(size: Long): ByteArray? {
return when {
size < 0L -> this.readBytes()
size == 0L -> ByteArray(0)
size > Int.MAX_VALUE -> null
else -> {
val sizeInt = size.toInt()
val result = ByteArray(sizeInt)
readBytesIntoByteArray(result, sizeInt)
result
}
}
}
fun InputStream.readBytesIntoByteArray(byteArray: ByteArray,bytesToRead:Int=byteArray.size) {
var offset = 0
while (true) {
val read = this.read(byteArray, offset, bytesToRead - offset)
if (read == -1)
break
offset += read
if (offset >= bytesToRead)
break
}
}
如果您知道大小,那么与其他解决方案相比,它可以节省两倍的内存(在很短的时间内,但仍然可能有用)。这是因为您必须将整个流读到末尾,然后将其转换为字节数组(类似于将数组转换为数组的ArrayList)。
例如,如果你在Android上,你有一些Uri要处理,你可以尝试用这个来获取大小:
fun getStreamLengthFromUri(context: Context, uri: Uri): Long {
context.contentResolver.query(uri, arrayOf(MediaStore.MediaColumns.SIZE), null, null, null)?.use {
if (!it.moveToNext())
return@use
val fileSize = it.getLong(it.getColumnIndex(MediaStore.MediaColumns.SIZE))
if (fileSize > 0)
return fileSize
}
//if you wish, you can also get the file-path from the uri here, and then try to get its size, using this: https://stackoverflow.com/a/61835665/878126
FileUtilEx.getFilePathFromUri(context, uri, false)?.use {
val file = it.file
val fileSize = file.length()
if (fileSize > 0)
return fileSize
}
context.contentResolver.openInputStream(uri)?.use { inputStream ->
if (inputStream is FileInputStream)
return inputStream.channel.size()
else {
var bytesCount = 0L
while (true) {
val available = inputStream.available()
if (available == 0)
break
val skip = inputStream.skip(available.toLong())
if (skip < 0)
break
bytesCount += skip
}
if (bytesCount > 0L)
return bytesCount
}
}
return -1L
}
请参阅InputStream.available()文档:
It is particularly important to realize that you must not use this method to size a container and assume that you can read the entirety of the stream without needing to resize the container. Such callers should probably write everything they read to a ByteArrayOutputStream and convert that to a byte array. Alternatively, if you're reading from a file, File.length returns the current length of the file (though assuming the file's length can't change may be incorrect, reading a file is inherently racy).
推荐文章
- 我如何修复一个NoSuchMethodError?
- Maven surefire找不到ForkedBooter类
- Java 8:我如何在流中使用异常抛出方法?
- 去下一次迭代在java For循环
- 在Java中使用什么数据类型来表示钱?
- Class.getResource()和ClassLoader.getResource()之间的区别是什么?
- 如何通过传递特定日期来确定星期几?
- 如何将DecimalFormat的小数分隔符从逗号更改为点/点?
- 控制jar工件的Maven最终名称
- Spring-MVC控制器中的404触发器?
- 为什么生成较长的serialVersionUID而不是简单的1L?
- JAX-RS / Jersey如何自定义错误处理?
- 从标准输入中捕获字符,而不需要等待按enter键
- 在执行JpaTest时无法找到@SpringBootConfiguration
- _JAVA_OPTIONS, JAVA_TOOL_OPTIONS和JAVA_OPTS之间的区别