Java ByteArrayInputStream

时间:2020-01-09 10:36:01  来源:igfitidea点击:

Java IO API的Java ByteArrayInputStream类java.io.ByteArrayInputStream使我们可以将字节数组中的数据作为字节流读取。换句话说,ByteArrayInputStream类可以将字节数组转换为InputStream。 ByteArrayInputStream类是InputStream类的子类,因此我们可以将ByteArrayInputStream用作InputStream。 " ByteArrayInputStream"还具有一组特定于" ByteArrayInputStream"类的其他方法。我将在本教程中介绍其中一些方法。

如果数据存储在数组中,则Java的ByteArrayInputStream可以派上用场,但是我们有一个只能将其作为InputStream进行处理的组件。因此," ByteArrayInputStream"可以包装字节数组,并将其转换为流。

创建一个ByteArrayInputStream

要使用Java" ByteArrayInputStream",必须首先创建" ByteArrayInputStream"类的实例。给构造函数传递要作为InputStream读取的字节数组。这是创建ByteArrayInputStream实例的示例:

byte[] bytes = ... //get byte array from somewhere.

ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);

这个例子创建了一个" ByteArrayInputStream",它可以读取传递给其构造函数的字节数组中的所有字节。

我们也可以告诉ByteArrayInputStream只读取给定字节数组的一部分。我们可以将额外的偏移量和长度传递给构造函数,该构造函数指定要读取的字节数组的哪一部分。看起来是这样的:

byte[] bytes = ... //get byte array from somewhere.

int offset = 20;
int length = 45;

ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes, offset, length);

这个例子创建了一个" ByteArrayInputStream",它将只读取从偏移量为20的字节开始的字节,并从其前的45个字节开始读取。

read()

我们可以通过Java的ByteArrayInputStream的read()方法从常规的InputStream的字节中读取字节。 read()将返回字节数组中的下一个字节,如果已到达字节数组(或者字节数组部分)的末尾,则返回-1. 这是从Java的ByteArrayInputStream读取字节的示例:

int data = byteArrayInputStream.read();
while(data != -1) {
  //do something with data

  data = byteArrayInputStream.read();
}

available()

Java的ByteArrayInputStream的available()方法告诉我们ByteArrayInputStream仍然有多少字节可用。这是一个例子:

int bytesAvailable = byteArrayInputStream.available();

mark()

ByteArrayInputStream类的mark()方法在当前字节位置设置一个内部标记,这意味着在读取前一个字节之后。 " mark()"方法采用一个参数,告诉它在该标记变为无效之前可以读取多少个字节。默认情况下,如果未显式设置标记,则ByteArrayInputStream标记的位置为0,或者标记为传递给其构造函数的偏移量的位置。这是一个通过ByteArrayInputStream的mark()方法设置标记的示例:

byte[] bytes = "abcdef".getBytes();

ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);

int data = byteArrayInputStream.read();  // read 'a'
    data = byteArrayInputStream.read();  // read 'b'
    data = byteArrayInputStream.read();  // read 'c'

    byteArrayInputStream.mark(1024);     // mark set before reading 'd'
    data = byteArrayInputStream.read();  // read 'd'
    data = byteArrayInputStream.read();  // read 'e'
    data = byteArrayInputStream.read();  // read 'f'

reset()

ByteArrayInputStream的reset()方法重置它已读入字节数组的距离。索引将被重置回到在ByteArrayInputStream上设置的最后一个标记。默认情况下,如果未显式设置标记,则ByteArrayInputStream标记的位置为0,或者标记为传递给其构造函数的偏移量的位置。这是一个使用ByteArrayInputStream``reset()方法的例子:

byte[] bytes = "abcdef".getBytes();

ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);

int data = byteArrayInputStream.read();  // read 'a'
    data = byteArrayInputStream.read();  // read 'b'
    data = byteArrayInputStream.read();  // read 'c'

    byteArrayInputStream.mark(1024);     // mark set before reading 'd'
    data = byteArrayInputStream.read();  // read 'd'
    data = byteArrayInputStream.read();  // read 'e'
    data = byteArrayInputStream.read();  // read 'f'

    byteArrayInputStream.reset();        // reset to mark before 'd'
    data = byteArrayInputStream.read();  // read 'd'
    data = byteArrayInputStream.read();  // read 'e'
    data = byteArrayInputStream.read();  // read 'f'

skip()

Java ByteArrayInputStreamskip()方法使我们可以跳过基础字节数组中的多个字节。我们将要跳过的字符数作为参数传递。这是一个使用ByteArrayInputStream``skip()方法跳过多个字节的示例:

byteArrayInputStream.skip(20);

关闭ByteArrayInputStream

完成Java的" ByteArrayInputStream"操作后,必须将其关闭。我们可以通过调用它的close()方法来关闭'ByteArrayInputStream'。这是一个打开ByteArrayInputStream,从中读取所有数据,然后关闭它的示例:

byte[] bytes = "abcdef".getBytes()

ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);

int data = byteArrayInputStream.read();
while(data != -1) {
  data = byteArrayInputStream.read();
}
byteArrayInputStream.close();

注意while循环如何继续,直到从ByteArrayInputStream的read()方法读取到-1为止。之后,while循环退出,并调用ByteArrayInputStreamclose()方法。

上面的代码不是100%健壮的。如果从ByteArrayInputStream读取数据时抛出异常,则永远不会调用close()方法。为了使代码更健壮,我们将必须使用Java try-with-resources构造。我在Java IO异常处理的教程中也解释了使用Java IO类的正确异常处理。

这是一个使用try-with-resources构造关闭JavaByteArrayInputStream的示例:

try( ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream("abcdef".getBytes()) ) {

    int data = byteArrayInputStream.read();
    while(data != -1){
        data = byteArrayInputStream.read();
    }
}

注意,在try关键字后的括号内现在声明了" ByteArrayInputStream"。这向Java发出信号,该" ByteArrayInputStream"将由try-with-resources结构进行管理。

一旦执行线程退出" try"块," byteArrayInputStream"变量将关闭。如果从try块内部抛出异常,则捕获该异常,关闭ByteArrayInputStream,然后重新抛出该异常。因此,当在try-with-resources块中使用时,可以确保ByteArrayInputStream是关闭的。