在Java中将二进制inputstream读入单个字节数组

该文档说,不应该使用available()方法来确定InputStream的大小。 如何将InputStream的整个内容读入一个字节数组?

 InputStream in; //assuming already present byte[] data = new byte[in.available()]; in.read(data);//now data is filled with the whole content of the InputStream 

我可以多次读取到一个固定大小的缓冲区,但是,我将不得不将所读取的数据组合到一个字节数组中,这对我来说是个问题。

最简单的方法是使用Guava和它的ByteStreams类:

 byte[] bytes = ByteStreams.toByteArray(in); 

或者为一个文件:

 byte[] bytes = Files.toByteArray(file); 

或者(如果你不想使用Guava),你可以创build一个ByteArrayOutputStream ,然后重复读入一个字节数组并写入ByteArrayOutputStream (让这个句柄resize),然后调用ByteArrayOutputStream.toByteArray()

请注意,无论您是否可以知道input的长度,这种方法都有效 – 当然,假设您有足够的内存。

如果你正在从一个文件中读取,你可以做这样的事情:

  File file = new File("myFile"); byte[] fileData = new byte[(int) file.length()]; DataInputStream dis = new DataInputStream(new FileInputStream(file)); dis.readFully(fileData); dis.close(); 

更新(2014年5月31日):

Java 7在java.nio.file包中添加了一些新function,可以使这个示例缩短几行。 请参阅java.nio.file.Files类中的readAllBytes()方法。 这里是一个简短的例子:

 import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; // ... Path p = FileSystems.getDefault().getPath("", "myFile"); byte [] fileData = Files.readAllBytes(p); 

请注意,截至本文写作之时,Android API不支持这个(或者Java 7中的任何东西)。

您可以使用Apache commons-io执行此任务:

参考这个方法 :

 public static byte[] readFileToByteArray(File file) throws IOException 

更新:

Java 7的方式:

 byte[] bytes = Files.readAllBytes(Paths.get(filename)); 

如果它是一个文本文件,并且您想将其转换为string(根据需要更改编码):

 StandardCharsets.UTF_8.decode(ByteBuffer.wrap(bytes)).toString() 

您可以通过块( byte buffer[] = new byte[2048] )读取它,并将块写入ByteArrayOutputStream。 从ByteArrayOutputStream你可以检索内容为一个字节[],而不需要事先确定它的大小。

我认为缓冲区的长度需要指定,因为内存是有限的,你可能会用尽

例:

 InputStream in = new FileInputStream(strFileName); long length = fileFileName.length(); if (length > Integer.MAX_VALUE) { throw new IOException("File is too large!"); } byte[] bytes = new byte[(int) length]; int offset = 0; int numRead = 0; while (offset < bytes.length && (numRead = in.read(bytes, offset, bytes.length - offset)) >= 0) { offset += numRead; } if (offset < bytes.length) { throw new IOException("Could not completely read file " + fileFileName.getName()); } in.close(); 

数组索引的最大值是Integer.MAX_INT – 约为2Gb(2 ^ 31/2 147 483 647)。 你的inputstream可能比2Gb大,所以你必须以块处理数据,对不起。

  InputStream is; final byte[] buffer = new byte[512 * 1024 * 1024]; // 512Mb while(true) { final int read = is.read(buffer); if ( read < 0 ) { break; } // do processing }