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();
}
/**
* method converts {@link InputStream} Object into byte[] array.
*
* @param stream the {@link InputStream} Object.
* @return the byte[] array representation of received {@link InputStream} Object.
* @throws IOException if an error occurs.
*/
public static byte[] streamToByteArray(InputStream stream) throws IOException {
byte[] buffer = new byte[1024];
ByteArrayOutputStream os = new ByteArrayOutputStream();
int line = 0;
// read bytes from stream, and store them in buffer
while ((line = stream.read(buffer)) != -1) {
// Writes bytes from byte array (buffer) into output stream.
os.write(buffer, 0, line);
}
stream.close();
os.flush();
os.close();
return os.toByteArray();
}
// Read the file contents into a byte[] array
byte[] buf = new byte[inputStreamLength];
int bytesRead = Math.max(0, inputStream.read(buf));
// If needed: for safety, truncate the array if the file may somehow get
// truncated during the read operation
byte[] contents = bytesRead == inputStreamLength ? buf
: Arrays.copyOf(buf, bytesRead);
/**
* Begin setup TCP connection to PC app
* to open integrate connection between mobile app and pc app (or mobile app)
*/
mSocket = new Socket(IP, port);
// mSocket.setSoTimeout(30000);
DataOutputStream mDos = new DataOutputStream(mSocket.getOutputStream());
String str = "MobileRequest#" + params[0] + "#<EOF>";
mDos.write(str.getBytes());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
/* Since data are accepted as byte, all of them will be collected in the
following byte array which initialised with accepted data length. */
DataInputStream mDis = new DataInputStream(mSocket.getInputStream());
byte[] data = new byte[mDis.available()];
// Collecting data into byte array
for (int i = 0; i < data.length; i++)
data[i] = mDis.readByte();
// Converting collected data in byte array into String.
String RESPONSE = new String(data);
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buffer = new byte[1024]; // you can configure the buffer size
int length;
while ((length = in.read(buffer)) != -1) out.write(buffer, 0, length); //copy streams
in.close(); // call this in a finally block
byte[] result = out.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#
我用这个。
rqqzpn5f8#
我知道为时已晚,但我认为这是一个更干净的解决方案,更具可读性。。。
rggaifut9#
如果您使用bytearrayoutputstream,您正在进行额外的复制。如果在开始读取流之前知道流的长度(例如,inputstream实际上是一个fileinputstream,您可以对该文件调用file.length(),或者inputstream是一个zipfile条目inputstream,您可以调用ZipPentry.length()),那么直接写入byte[]数组要好得多——它使用了一半的内存,而且节省时间。
n、 b.如果您需要处理这种可能性,则上面的最后一行处理在读取流时被截断的文件,但如果在读取流时文件变长,则byte[]数组中的内容将不会加长以包含新的文件内容,数组将被截断为原来的长度inputstreamlength。
carvr3hs10#
另一种情况是在向服务器发送请求并等待响应之后,通过流获取正确的字节数组。
xmq68pz911#
在将s3对象转换为bytearray时,我们看到了一些aws事务的延迟。
注:s3对象是pdf文档(最大大小为3MB)。
我们使用选项#1(org.apache.commons.io.ioutils)将s3对象转换为bytearray。我们注意到s3提供了内置ioutils方法来将s3对象转换为bytearray,我们要求您确认将s3对象转换为bytearray的最佳方式是什么,以避免延迟。
选项1:
选项2:
另外,如果我们有其他更好的方法将s3对象转换为bytearray,请告诉我
8yoxcaq712#
java 8路(感谢bufferedreader和adam bien)
请注意,此解决方案会擦除回车符('\r'),可能不合适。
vfh0ocws13#
将它 Package 在datainputstream中,如果出于某种原因,它不在表中,只需使用read来敲打它,直到它给出-1或您要求的整个块。
smtd7mpg14#
见
InputStream.available()
文档:特别重要的是要认识到,您不能使用此方法来调整容器的大小,并假设您可以读取整个流,而无需调整容器的大小。此类调用者可能应该将读取的所有内容写入bytearrayoutputstream,并将其转换为字节数组。或者,如果您正在读取文件,file.length将返回文件的当前长度(尽管假设文件的长度不能更改可能是不正确的,但读取文件本身就是快速的)。
xghobddn15#
我试图编辑@numan的答案,并修复了写入垃圾数据的问题,但编辑被拒绝。虽然这段代码并不精彩,但我看不到其他更好的答案。以下是对我最有意义的:
顺便说一句,bytearrayoutputstream无需关闭。try/finally结构因可读性而省略