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

时间:2011-08-30 21:50:25

标签: java inputstream

The documentation表示不应使用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

我可以多次读入固定大小的缓冲区,但是,我必须将读取的数据合并为单个字节数组,这对我来说是一个问题。

6 个答案:

答案 0 :(得分:61)

最简单的方法IMO是使用Guava及其ByteStreams类:

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

或者是文件:

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

或者(如果您不想使用Guava),您可以创建一个ByteArrayOutputStream,并重复读入一个字节数组并写入ByteArrayOutputStream(让该句柄调整大小),然后致电ByteArrayOutputStream.toByteArray()

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

答案 1 :(得分:55)

如果您正在阅读文件,可以执行以下操作:

    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包中添加了一些新功能,可用于使此示例缩短几行。请参阅readAllBytes()课程中的java.nio.file.Files方法。这是一个简短的例子:

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中的大部分内容)。

答案 2 :(得分:9)

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

请参阅this method

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()

答案 3 :(得分:5)

您可以通过块(byte buffer[] = new byte[2048])读取它并将块写入ByteArrayOutputStream。从ByteArrayOutputStream中,您可以将内容检索为byte [],而无需事先确定其大小。

答案 4 :(得分:4)

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

示例:

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();

答案 5 :(得分:3)

数组索引的最大值是Integer.MAX_INT - 它大约是2Gb(2 ^ 31/2 147 483 647)。 您的输入流可能大于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 
        }