如何将整个输入流读到字节数组?
当前回答
我用这个。
public static byte[] toByteArray(InputStream is) throws IOException {
ByteArrayOutputStream output = new ByteArrayOutputStream();
try {
byte[] b = new byte[4096];
int n = 0;
while ((n = is.read(b)) != -1) {
output.write(b, 0, n);
}
return output.toByteArray();
} finally {
output.close();
}
}
其他回答
另一种情况是在发送请求到服务器并等待响应后,通过流获得正确的字节数组。
/**
* 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);
安全解决方案(正确关闭流):
Java 9及更新版本: 最终字节[]字节; try (inputStream) { 字节= inputStream.readAllBytes(); }
Java 8 and older: 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::类) fun InputStream.readAllBytes(): ByteArray { val bufLen = 4 * 0x400 // 4KB val buf = ByteArray(bufLen) var readLen: Int = 0 ByteArrayOutputStream()。使用{o -> 这一点。使用{I -> i.read(buf, 0, bufLen)。{readLen = it} != -1) o.write(buf, 0, readLen) } 返回o.toByteArray () } } 避免嵌套使用请看这里。
Scala(当Java 9+不可访问时)(By @Joan。Thx): def readAllBytes(inputStream: inputStream): Array[Byte] = Stream.continually (read)。takeWhile(_ != -1).map(_. tobyte).toArray . take (_
您需要从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();
您可以使用Apache Commons IO来处理这个任务和类似的任务。
IOUtils类型有一个静态方法来读取InputStream并返回一个字节[]。
InputStream is;
byte[] bytes = IOUtils.toByteArray(is);
这将在内部创建一个ByteArrayOutputStream并将字节复制到输出,然后调用toByteArray()。它通过以4KiB为块复制字节来处理大文件。
您可以使用cactoos库提供可重用的面向对象的Java组件。 这个库强调OOP,因此没有静态方法、null等等,只有真实对象及其契约(接口)。 像读取InputStream这样的简单操作可以这样执行
final InputStream input = ...;
final Bytes bytes = new BytesOf(input);
final byte[] array = bytes.asBytes();
Assert.assertArrayEquals(
array,
new byte[]{65, 66, 67}
);
使用专用类型Bytes来处理数据结构byte[]使我们能够使用OOP策略来解决手头的任务。 一些程序性的“效用”方法将禁止我们做的事情。 例如,您需要将从此InputStream读取的字节封装到Base64。 在本例中,您将使用Decorator模式并在Base64的实现中封装Bytes对象。 Cactoos已经提供了这样的实现:
final Bytes encoded = new BytesBase64(
new BytesOf(
new InputStreamOf("XYZ")
)
);
Assert.assertEquals(new TextOf(encoded).asString(), "WFla");
您可以使用Decorator模式以同样的方式解码它们
final Bytes decoded = new Base64Bytes(
new BytesBase64(
new BytesOf(
new InputStreamOf("XYZ")
)
)
);
Assert.assertEquals(new TextOf(decoded).asString(), "XYZ");
无论你的任务是什么,你都可以创建自己的Bytes实现来解决它。
推荐文章
- 我如何修复一个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之间的区别