final InputStream input = ...;
final Bytes bytes = new BytesOf(input);
final byte[] array = bytes.asBytes();
Assert.assertArrayEquals(
array,
new byte[]{65, 66, 67}
);
final Bytes encoded = new BytesBase64(
new BytesOf(
new InputStreamOf("XYZ")
)
);
Assert.assertEquals(new TextOf(encoded).asString(), "WFla");
您可以使用装饰器模式以相同的方式解码它们
final Bytes decoded = new Base64Bytes(
new BytesBase64(
new BytesOf(
new InputStreamOf("XYZ")
)
)
);
Assert.assertEquals(new TextOf(decoded).asString(), "XYZ");
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
}
@SuppressWarnings("empty-statement")
public static byte[] inputStreamToByte(InputStream is) throws IOException {
if (is == null) {
return null;
}
// Define a size if you have an idea of it.
ByteArrayOutputStream r = new ByteArrayOutputStream(2048);
byte[] read = new byte[512]; // Your buffer size.
for (int i; -1 != (i = is.read(read)); r.write(read, 0, i));
is.close();
return r.toByteArray();
}
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();
}
30条答案
按热度按时间ca1c2owp1#
您可以将cactoos库用于提供可重用的面向对象java组件。这个库强调oop,所以没有静态方法、null等,只有真实对象及其契约(接口)。像读取inputstream这样的简单操作可以这样执行
有专用类型的
Bytes
用于处理数据结构byte[]
使我们能够使用面向对象的策略来解决手头的任务。程序性“实用”方法禁止我们做的事情。例如,您需要加密从该文件读取的字节InputStream
到base64。在本例中,您将在base64的实现中使用decorator模式和wrap bytes对象。cactoos已经提供了这样的实现:您可以使用装饰器模式以相同的方式解码它们
无论您的任务是什么,您都将能够创建自己的实现
Bytes
解决它。mrphzbgm2#
kotlin中的解决方案(当然也可以在java中使用),它包括两种情况,即您是否知道大小:
如果您知道大小,那么与其他解决方案相比,它可以节省两倍的内存使用量(在很短的时间内,但仍然可能有用)。这是因为您必须将整个流读取到底,然后将其转换为字节数组(类似于将arraylist转换为数组)。
因此,例如,如果您在android上,并且需要处理一些uri,您可以尝试使用以下方法获取大小:
kuhbmx9i3#
以下是一个优化版本,它尝试尽可能避免复制数据字节:
ltskdhd14#
您可以尝试cactoos:
3j86kqsm5#
java 7及更高版本:
o3imoua46#
这是我的复制粘贴版本:
blmhpbnm7#
我用这个。
nhjlsmyf8#
您可以使用ApacheCommonsIO来处理此任务和类似的任务。
这个
IOUtils
类型有一个静态方法来读取InputStream
并返回一个byte[]
.这在内部创建了一个
ByteArrayOutputStream
并将字节复制到输出,然后调用toByteArray()
. 它通过复制4KB块中的字节来处理大型文件。gk7wooem9#
您需要从数据库中读取每个字节
InputStream
然后写给一个ByteArrayOutputStream
.然后,您可以通过调用
toByteArray()
:fkvaft9z10#
最后,二十年后,由于java 9,有了一个不需要第三方库的简单解决方案:
还要注意方便的方法
readNBytes(byte[] b, int off, int len)
及transferTo(OutputStream)
解决经常性需要。xe55xuns11#
使用香草java的
DataInputStream
及其readFully
方法(至少从java 1.4开始存在):这个方法还有其他一些风格,但我一直在这个用例中使用它。
agxfikkp12#
如果你碰巧使用谷歌Guava,它将与使用谷歌Guava一样简单
ByteStreams
:6mzjoqzu13#
一如既往,spring框架(自3.2.2以来的spring核心)也为您提供了一些东西:
StreamUtils.copyToByteArray()
7lrncoxx14#
5tmbdcev15#
安全解决方案(具有
close
流(正确):java 9+:
java 8:
kotlin(当无法访问java 9+时):
避免嵌套
use
看这里。scala(当java 9+不可访问时)(作者@joan。thx):