Java ByteArrayInputStream
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
是关闭的。