有时候我们的数据来源或目的地并不是一个文件,也有可能是直接来自于内存(譬如一个字符串,一个数组),Java给我们提供了一系列针对数组的输出输出流,他们是
ByteArrayInputStream
ByteArrayOutputStream
CharArrayReader
CharArrayWriter
ByteArrayOutputStream中也包含一个内部缓冲区,该缓冲区就是我们要从流中读取的内容,我们通过read方法去读取缓冲区中的内容
ByteArrayInputStream(byte[] buf)
创建一个 ByteArrayInputStream,使用 buf 作为其缓冲区数组。
ByteArrayInputStream(byte[] buf, int offset, int length)
创建 ByteArrayInputStream,使用 buf 作为其缓冲区数组。
available()
返回可从此输入流读取(或跳过)的剩余字节数。
close()
关闭 ByteArrayInputStream 无效。
mark(int readAheadLimit)
设置流中的当前标记位置。
markSupported()
测试此 InputStream 是否支持 mark/reset。
read()
从此输入流中读取下一个数据字节。
read(byte[] b, int off, int len)
将最多 len 个数据字节从此输入流读入 byte 数组。
reset()
将缓冲区的位置重置为标记位置。
skip(long n)
从此输入流中跳过 n 个输入字节。
ByteArrayInputStream 的close方法没有执行任何内容,调用无效。mark方法的参数也没有任何意义。
在ByteArrayOutputStream使用一个byte作为缓冲区,我们写出的数据会被写入到这个字节数组中,可以使用toByteArray()和toString()方法获取到缓冲区内数据。该字节数组会随着数据的写入不断扩大。
ByteArrayOutputStream()
创建一个新的 byte 数组输出流。
ByteArrayOutputStream(int size)
创建一个新的 byte 数组输出流,它具有指定大小的缓冲区容量(以字节为单位)。
close()
关闭 ByteArrayOutputStream 无效。
reset()
将此 byte 数组输出流的 count 字段重置为零,从而丢弃输出流中目前已累积的所有输出。
size()
返回缓冲区的当前大小。
toByteArray()
创建一个新分配的 byte 数组。
toString()
使用平台默认的字符集,通过解码字节将缓冲区内容转换为字符串。
toString(String charsetName)
使用指定的 charsetName,通过解码字节将缓冲区内容转换为字符串。
write(byte[] b, int off, int len)
将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此 byte 数组输出流。
write(int b)
将指定的字节写入此 byte 数组输出流。
writeTo(OutputStream out)
将此 byte 数组输出流的全部内容写入到指定的输出流参数中,这与使用 out.write(buf, 0, count) 调用该输出流的 write 方法效果一样。
ByteArrayOutputStream 的close方法没有执行任何内容,调用无效。
和ByteArrayOutputStream 差不多,只不过CharArrWriter内部的缓冲区是一个char数组,这个char数组也会随着写入数据不断扩大。
该类的flush和close都没有执行任何操作,所以调用CharArrayWriter的flush和close方法没有任何作用。
CharArrayWriter()
创建一个新的 CharArrayWriter。
CharArrayWriter(int initialSize)
创建一个具有指定初始大小的新 CharArrayWriter。
append(char c)
将指定字符添加到此 writer。
append(CharSequence csq)
将指定的字符序列添加到此 writer。
append(CharSequence csq, int start, int end)
将指定字符序列的子序列添加到此 writer。
close()
关闭该流。
flush()
刷新该流的缓冲。
reset()
重置该缓冲区,以便再次使用它而无需丢弃已分配的缓冲区。
size()
返回缓冲区的当前大小。
toCharArray()
返回输入数据的副本。
toString()
将输入数据转换为字符串。
write(char[] c, int off, int len)
将字符写入缓冲区。
write(int c)
将一个字符写入缓冲区。
write(String str, int off, int len)
将字符串的某一部分写入缓冲区。
writeTo(Writer out)
将缓冲区的内容写入另一个字符流。
CharArrayReader 和 ByteArrayInputStream 一样,只不过内部缓冲区是一个字符数组。
mark方法的参数在这里没有任何意义。
CharArrayReader(char[] buf)
根据指定的 char 数组创建一个 CharArrayReader。
CharArrayReader(char[] buf, int offset, int length)
根据指定的 char 数组创建一个 CharArrayReader。
close()
关闭该流并释放与之关联的所有系统资源。
mark(int readAheadLimit)
标记流中的当前位置。
markSupported()
判断此流是否支持 mark() 操作(它一定支持)。
read()
读取单个字符。
read(char[] b, int off, int len)
将字符读入数组的某一部分。
ready()
判断此流是否已准备好被读取。
reset()
将该流重置为最新的标记,如果从未标记过,则将其重置到开头。
skip(long n)
跳过字符。
public class ArrayStreamTest {
private ByteArrayInputStream bais;
private ByteArrayOutputStream baos;
private CharArrayWriter writer;
private CharArrayReader reader;
private String str;
private FileOutputStream fos;
private FileWriter fileWriter;
public static void main(String[] args) {
ArrayStreamTest arrayStreamTest = new ArrayStreamTest();
arrayStreamTest.byteArrayOutputTest();
arrayStreamTest.byteArrayInputTest();
arrayStreamTest.charArrayWriterTest();
arrayStreamTest.charArrayReadTest();
}
private void charArrayWriterTest() {
try {
writer = new CharArrayWriter();
fileWriter = new FileWriter(new File("D:\\CharArrayWriter.txt"));
writer.write("abcde".toCharArray()); // 向缓冲区写入字符数组
writer.write((int) 'f'); // 向缓冲区写入单个字符
writer.write("ghij".toCharArray(), 0, 4); // 向缓冲区写入字符数组的一部分
writer.write("klmno"); // 向缓冲区写入字符串
writer.write("pqrst", 0, 5); // 向缓冲区写入字符串的一部分
writer.append('u'); // 向流中添加单个字符
CharSequence cs1 = "vw";
CharSequence cs2 = "xyz";
writer.append(cs1); // 向流中添加字符序列
writer.append(cs2, 0, 3);// 向流中添加字符序列的一部分
str = writer.toString(); // 将输入数据转换为字符串
System.out.println(writer.toCharArray().length);// 输出输入数据的副本长度
writer.writeTo(fileWriter);// 将缓冲区的内容写入另一个字符流。
writer.flush();// 刷新CharArrayWriter,该动作无效
fileWriter.flush();
writer.reset(); // 重置缓冲区
System.out.println(writer.size());// 输出此时缓冲区大小,因为之前已经调用reset方法重置,故输出为0
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
if (fileWriter != null) {
fileWriter.close();
}
if (writer != null) {
writer.close(); // 关闭CharArrayWriter,但该动作无效
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void charArrayReadTest() {
try {
reader = new CharArrayReader(str.toCharArray());
boolean marked = false;
if (reader.markSupported()) {
reader.mark(100); //在流中标记位置,该方法参数无意义
marked = true;
} else {
System.out.println("不支持mark、reset方法");
}
int i = 0;
while ((i = reader.read()) != -1) {//读取单个字符
if (marked & i == 'f') {
reader.reset(); //读取f字符,则重置流至标记处
marked = false;
}
if (i == 'g') {
reader.skip(5); //遇到字符g,则跳过5个字符
break;
}
System.out.print((char) i);
}
int length = 0;
char[] arr = new char[2];
while ((length = reader.read(arr)) != -1) {
System.out.print(new String(arr, 0, length));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
reader.close();
}
}
}
private void byteArrayInputTest() {
bais = new ByteArrayInputStream(str.getBytes());
if (bais.markSupported()) {
System.out.println("ByteArrayInputStream 支持mark、reset方法");
bais.mark(0);// 在流中做标记,在ByteArrayInputStream中,mark方法的参数不起作用。
} else {
System.out.println("ByteArrayInputStream 不支持mark、reset方法");
}
System.out.println((char) bais.read()); // 读取一个字节
System.out.println(bais.available()); // 剩余刻度或者可跳过字节
bais.skip(1);// 跳过1个字节
try {
int length = 0;
byte[] arr = new byte[2];
while ((length = bais.read(arr)) != -1) {
System.out.print(new String(arr, 0, length));
}
bais.reset(); // 重置缓冲区标志,回到mark处
System.out.println("\n" + bais.available());
} catch (IOException e) {
e.printStackTrace();
}
}
private void byteArrayOutputTest() {
try {
baos = new ByteArrayOutputStream();
fos = new FileOutputStream(new File("D:\\text.txt"));
baos.write(65);
baos.write("BCDE".getBytes());
baos.close(); // 关闭ByteArrayOutputStream无效。依旧可以继续操作。
baos.write("FGHIJKLMN".getBytes(), 0, 5);
System.out.println("此时缓冲数组中数据长度为: " + baos.size()); // 输出缓冲区的当前大小并写出
str = baos.toString(); // 将缓冲区内容转换为字符串
System.out.println(baos.toByteArray().length);// 将缓冲区内容转为字节数组并写出长度
baos.writeTo(fos); // 将流中数据写入到一个文件输出流中
baos.reset();// 丢弃流中所有数据
System.out.println("此时缓冲数组中数据长度为: " + baos.size()); // 输出此时流中的数据长度:结果为0
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fos != null) {
fos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}