我该如何将整个InputStream
读入字节数组中?
我该如何将整个InputStream
读入字节数组中?
Java 8的方法(感谢BufferedReader和Adam Bien)
private static byte[] readFully(InputStream input) throws IOException {
try (BufferedReader buffer = new BufferedReader(new InputStreamReader(input))) {
return buffer.lines().collect(Collectors.joining("\n")).getBytes(<charset_can_be_specified>);
}
}
\r
可能会成为问题。该方法将字节转换为字符,然后再次转换为字节(使用InputStreamReader的默认字符集)。任何在默认字符编码中无效的字节(例如,在Linux上对于UTF-8为-1)都将被破坏,甚至可能改变字节数。 - seanf这里有一个经过优化的版本,尽量避免复制数据字节:
private static byte[] loadStream (InputStream stream) throws IOException {
int available = stream.available();
int expectedSize = available > 0 ? available : -1;
return loadStream(stream, expectedSize);
}
private static byte[] loadStream (InputStream stream, int expectedSize) throws IOException {
int basicBufferSize = 0x4000;
int initialBufferSize = (expectedSize >= 0) ? expectedSize : basicBufferSize;
byte[] buf = new byte[initialBufferSize];
int pos = 0;
while (true) {
if (pos == buf.length) {
int readAhead = -1;
if (pos == expectedSize) {
readAhead = stream.read(); // test whether EOF is at expectedSize
if (readAhead == -1) {
return buf;
}
}
int newBufferSize = Math.max(2 * buf.length, basicBufferSize);
buf = Arrays.copyOf(buf, newBufferSize);
if (readAhead != -1) {
buf[pos++] = (byte)readAhead;
}
}
int len = stream.read(buf, pos, buf.length - pos);
if (len < 0) {
return Arrays.copyOf(buf, pos);
}
pos += len;
}
}
我使用这个。
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();
}
}
这是我的复制粘贴版本:
@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();
}
import sun.misc.IOUtils;
...
InputStream in = ...;
byte[] buf = IOUtils.readFully(in, -1, false);
sun.misc.IOUtils
并不是“Java 7”的一部分。它是一个专有的、实现特定的类,在其他JRE实现中可能不存在,并且在接下来的版本中可能会没有任何警告地消失。 - Holger这对我有效,
if(inputStream != null){
ByteArrayOutputStream contentStream = readSourceContent(inputStream);
String stringContent = contentStream.toString();
byte[] byteArr = encodeString(stringContent);
}
readSourceContent()
public static ByteArrayOutputStream readSourceContent(InputStream inputStream) throws IOException {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
int nextChar;
try {
while ((nextChar = inputStream.read()) != -1) {
outputStream.write(nextChar);
}
outputStream.flush();
} catch (IOException e) {
throw new IOException("Exception occurred while reading content", e);
}
return outputStream;
}
encodeString()
:public static byte[] encodeString(String content) throws UnsupportedEncodingException {
byte[] bytes;
try {
bytes = content.getBytes();
} catch (UnsupportedEncodingException e) {
String msg = ENCODING + " is unsupported encoding type";
log.error(msg,e);
throw new UnsupportedEncodingException(msg, e);
}
return bytes;
}
String
,然后再转换为byte[]
(这可能会影响二进制数据)? ByteArrayOutputStream
有.toByteArray()
方法:https://docs.oracle.com/javase/7/docs/api/java/io/ByteArrayOutputStream.html#toByteArray() - Thomas Perl你可以使用Cactoos(我是其中的开发者之一):
import org.cactoos.bytes.BytesOf;
byte[] array = new BytesOf(stream).asBytes();
你也可以将流转换为 String
:
import org.cactoos.text.TextOf;
String txt = new TextOf(stream).asString();
asBytes()
和asString()
方法都会抛出受检查的Exception
。如果你不想捕获它,可以使用Unchecked*
修饰符,例如:
import org.cactoos.bytes.BytesOf;
import org.cactoos.bytes.UncheckedBytes;
byte[] array = new UncheckedBytes(new BytesOf(stream)).asBytes();
另一种情况是通过流获取正确的字节数组,在向服务器发送请求并等待响应后。
/**
* 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);
// 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);
注意:上面的最后一行涉及到在读取流时文件被截断的情况,如果您需要处理这种可能性,但如果文件在读取流时变得更长,则byte[]数组中的内容将不会被延长以包括新的文件内容,该数组将仅被截断为旧长度。