内存操作流
之前的所有的流操作都是针对文件的,但是有时候只是想要实现数据间转换,此时如果我们想要创建一个文件然后再删除文件,那样显得有点麻烦,因此此时的内存操作流就显得很适合这类的操作,因为它只是在内存中存储,并不会真正的创建文件,内存操作流涉及的两个类是
ByteArrayInputStream
,ByteArrayOutputStream
.
ByteArrayInputStream
ByteArrayInputStream
包含一个内部缓冲区,该缓冲区包含从流中读取的字节。内部计数器跟踪read
方法要提供的下一个字节。- 关闭
ByteArrayInputStream
无效。此类中的方法在关闭此流后仍可被调用,而不会产生任何IOException
。- 主要的功能是从缓冲区读取字节
构造函数
ByteArrayInputStream(byte[] buf)
创建一个ByteArrayInputStream
,使用buf
作为其缓冲区数组。ByteArrayInputStream(byte[] buf, int offset, int length)
创建ByteArrayInputStream
,使用 buf 作为其缓冲区数组。
常用的方法
close()
不过对这个无效,因为关闭之后仍然可以使用函数读取而不报错int read()
从缓冲区中读取一个字节int read(byte[] bytes)
将缓冲区中的内容读取到数组中int read(byte[] bytes,int off,int len)
将最多len
个数据字节从此输入流读入byte
数组。long skip(long n)
从此输入流中跳过n
个输入字节。void reset()
将此 byte 数组输出流的 count 字段重置为零,从而丢弃输出流中目前已累积的所有输出(清除缓冲区)
实例
public class demo8 {
public static void main(String args[]) {
String str = "chenjiabing\n陈加兵";
byte[] bytes = str.getBytes(); //创建一个数组
ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes); //使用bytes作为缓冲区数组
int temp = 0;
/*第一种方法读取缓冲区中的数据,这个和文件的操作不一样,这个可以直接冲缓冲区中读取数据字节*/
while ((temp = inputStream.read()) != -1) {
System.out.print((char) temp);
}
/*创建数组用于存储读取的内容,下面是第二种读取数据的方法*/
byte[] b = new byte[bytes.length];
try {
int len = inputStream.read(b);
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(new String(b));
}
}
ByteArrayOutputStream
- 此类实现了一个输出流,其中的数据被写入一个
byte
数组。缓冲区会随着数据的不断写入而自动增长。可使用toByteArray()
和 toString() 获取数据。
- 关闭
ByteArrayOutputStream
无效。此类中的方法在关闭此流后仍可被调用,而不会产生任何IOException
。
构造函数
ByteArrayOutputStream()
创建一个新的byte
数组输出流。ByteArrayOutputStream(int size)
创建一个新的byte
数组输出流,它具有指定大小的缓冲区容量(以字节为单位)。
常用函数
int size()
返回缓冲区的当前大小。
byte[] toByteArray()
创建一个新分配的byte
数组。
String toString()
将缓冲区的字节转换成字符串
void write(byte[] b, int off, int len)
将指定byte
数组中从偏移量off
开始的len
个字节写入此byte
数组输出流。
void write(int b)
将指定的字节写入此byte
数组输出流。
实例
public class demo8 {
public static void main(String args[]) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
String str = "chenjiabing";
try {
outputStream.write(str.getBytes()); //将字符串转换成数组然后写入缓冲区
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
outputStream.close(); //这里的关闭无效
} catch (IOException e) {
e.printStackTrace();
}
}
//将缓冲区的数据转换成字符串后输出,这里同样可以看出输出流的关闭根本不影响函数的调用
System.out.println(outputStream.size()); //输出缓冲区的大小
System.out.println(outputStream.toString()); //输出chenjiabing
outputStream.reset(); //清除缓冲区的内容,如果不清零那么原先写入的数据还是存在的,但是此时我们已经不需要前面的数据了
try {
outputStream.write("陈加兵".getBytes()); //继续向缓冲区写入数据
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(outputStream.size()); //这里的一个汉字占了三个字节
System.out.println(outputStream.toString());//输出陈加兵
}
}
综合
下面我们结合上面的两个类将字符串转换大小写
public class demo8 {
public static void main(String args[]) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
String str = "chenjiabing";
ByteArrayInputStream inputStream = new ByteArrayInputStream(str.getBytes()); //实例化输入流
int temp = 0;
while ((temp = inputStream.read()) != -1) //读取缓冲区的字节数据
{
char c = (char) temp; //将整数转换成字符,ascii码的转换
outputStream.write(Character.toUpperCase(c)); //转换成大写,然后写入输出流的缓冲区中
}
System.out.println(outputStream.toString()); //利用输出流输出转换后的字符串,即是去取出内存中的数据
}
}