我该如何将整个InputStream
读入字节数组中?
我该如何将整个InputStream
读入字节数组中?
如果您不想使用Apache commons-io库,可以使用sun.misc.IOUtils类中的此代码片段。与使用ByteBuffers的常用实现相比,它近乎快了一倍:
public static byte[] readFully(InputStream is, int length, boolean readAll)
throws IOException {
byte[] output = {};
if (length == -1) length = Integer.MAX_VALUE;
int pos = 0;
while (pos < length) {
int bytesToRead;
if (pos >= output.length) { // Only expand when there's no room
bytesToRead = Math.min(length - pos, output.length + 1024);
if (output.length < pos + bytesToRead) {
output = Arrays.copyOf(output, pos + bytesToRead);
}
} else {
bytesToRead = output.length - pos;
}
int cc = is.read(output, pos, bytesToRead);
if (cc < 0) {
if (readAll && length != Integer.MAX_VALUE) {
throw new EOFException("Detect premature EOF");
} else {
if (output.length != pos) {
output = Arrays.copyOf(output, pos);
}
break;
}
}
pos += cc;
}
return output;
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
while (true) {
int r = in.read(buffer);
if (r == -1) break;
out.write(buffer, 0, r);
}
byte[] ret = out.toByteArray();
Input Stream is ...
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int next = in.read();
while (next > -1) {
bos.write(next);
next = in.read();
}
bos.flush();
byte[] result = bos.toByteArray();
bos.close();
@Adamski:您可以完全避免缓冲区。
代码来自http://www.exampledepot.com/egs/java.io/File2ByteArray.html(是的,它非常冗长,但需要的内存空间仅为其他解决方案的一半。)
// Returns the contents of the file in a byte array.
public static byte[] getBytesFromFile(File file) throws IOException {
InputStream is = new FileInputStream(file);
// Get the size of the file
long length = file.length();
// You cannot create an array using a long type.
// It needs to be an int type.
// Before converting to an int type, check
// to ensure that file is not larger than Integer.MAX_VALUE.
if (length > Integer.MAX_VALUE) {
// File is too large
}
// Create the byte array to hold the data
byte[] bytes = new byte[(int)length];
// Read in the bytes
int offset = 0;
int numRead = 0;
while (offset < bytes.length
&& (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) {
offset += numRead;
}
// Ensure all the bytes have been read in
if (offset < bytes.length) {
throw new IOException("Could not completely read file "+file.getName());
}
// Close the input stream and return bytes
is.close();
return bytes;
}
offset < bytes.length
,则应添加 is.close()
,否则如果抛出异常,InputStream
将不会被关闭。 - Jared RummlerJava 9将为您提供一个很棒的方法:
InputStream in = ...;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
in.transferTo( bos );
byte[] bytes = bos.toByteArray();
InputStram.readAllBytes()
的区别是什么?InputStram.readAllBytes()
是一行代码的形式。 - Slava SemushinByteArrayOutputStream
中肯定有很多数组调整大小的操作,接着是数据的完全复制。 - Maarten Bodewesimport org.apache.commons.io.IOUtils;
is = s3object.getObjectContent();
content =IOUtils.toByteArray(is);
选项#2:
import com.amazonaws.util.IOUtils;
is = s3object.getObjectContent();
content =IOUtils.toByteArray(is);
如果我们有其他更好的方法将S3对象转换为字节数组,请告诉我。
我知道现在已经很晚了,但是我认为这里有一个更干净、更易读的解决方案...
/**
* 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();
}
我尝试编辑@numan的答案,为了解决写入垃圾数据的问题,但是我的编辑被拒绝了。虽然这段代码并不是很出色,但我看不到其他更好的答案。以下是对我来说最有意义的代码:
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();
请参考 InputStream.available()
的文档:
需要特别注意的是,您不能使用此方法来确定容器的大小,并假设您可以在不需要调整容器大小的情况下读取流的全部内容。这样的调用者可能应该将它们读取的所有内容写入 ByteArrayOutputStream 并将其转换为字节数组。或者,如果您正在从文件中读取,则 File.length 返回文件的当前长度(尽管假定文件的长度不会更改可能是不正确的,从文件中读取本质上存在竞争条件)。
如果无法使用DataInputStream,请将其包装在其中,只需使用read命令不断尝试读取,直到返回-1或您要求的整个块为止。
public int readFully(InputStream in, byte[] data) throws IOException {
int offset = 0;
int bytesRead;
boolean read = false;
while ((bytesRead = in.read(data, offset, data.length - offset)) != -1) {
read = true;
offset += bytesRead;
if (offset >= data.length) {
break;
}
}
return (read) ? offset : -1;
}