本小节会简要概括Java IO中字节数组与过滤器的输入输出流,主要涉及以下4个类型的流:ByteArrayInputStream,ByteArrayOutputStream,FilterInputStream,FilterOutputStream。
ByteArray和Filter
1.1 ByteArrayInputStream
byte[] bytes = ... //get byte array from somewhere.
InputStream input = new ByteArrayInputStream(bytes);
int data = input.read();
while(data != -1) {
//do something with data
data = input.read();
}
input.close();
如果数据存储在数组中,ByteArrayInputStream可以很方便地读取数据。如果你有一个InputStream变量,又想从数组中读取数据呢?很简单,只需要把字节数组传递给ByteArrayInputStream的构造函数,在把这个ByteArrayInputStream赋值给InputStream变量就可以了(译者注:InputStream是所有字节输入流流的基类,Reader是所有字符输入流的基类,OutputStream与Writer同理)。
1.2 ByteArrayOutputStream
ByteArrayOutputStream允许你以数组的形式获取写入到该输出流中的数据
ByteArrayOutputStream output = new ByteArrayOutputStream();
//write data to output stream
byte[] bytes = output.toByteArray();
1.3 FilterInputStream
FilterInputStream是实现自定义过滤输入流的基类,基本上它仅仅只是覆盖了InputStream中的所有方法。
1.4 FilterOutputStream
内容同FilterInputStream
Buffered和Data
Java IO中Buffered和data的输入输出流,主要涉及以下4个类型的流:BufferedInputStream,BufferedOutputStream,DataInputStream,DataOutputStream。
2.1 BufferedInputStream
BufferedInputStream能为输入流提供缓冲区,能提高很多IO的速度。你可以一次读取一大块的数据,而不需要每次从网络或者磁盘中一次读取一个字节。特别是在访问大量磁盘数据时,缓冲通常会让IO快上许多。
为了给你的输入流加上缓冲,你需要把输入流包装到BufferedInputStream中
InputStream input = new BufferedInputStream(new FileInputStream("c:\\data\\input-file.txt"));
你可以给BufferedInputStream的构造函数传递一个值,设置内部使用的缓冲区设置大小(译者注:默认缓冲区大小8 * 1024B)
InputStream input = new BufferedInputStream(new FileInputStream("c:\\data\\input-file.txt"), 8 * 1024);
这个例子设置了8KB的缓冲区。最好把缓冲区大小设置成1024字节的整数倍,这样能更高效地利用内置缓冲区的磁盘。
除了能够为输入流提供缓冲区以外,其余方面BufferedInputStream基本与InputStream类似。
2.2 BufferedOutputStream
与BufferedInputStream类似,BufferedOutputStream可以为输出流提供缓冲区。可以构造一个使用默认大小缓冲区的BufferedOutputStream(译者注:默认缓冲区大小8 * 1024B)
OutputStream output = new BufferedOutputStream(new FileOutputStream("c:\\data\\output-file.txt"));
也可以手动设置缓冲区大小
OutputStream output = new BufferedOutputStream(new FileOutputStream("c:\\data\\output-file.txt"), 8 * 1024);
2.3 DataInputStream
DataInputStream可以使你从输入流中读取Java基本类型数据,而不必每次读取字节数据。你可以把InputStream包装到DataInputStream中,然后就可以从此输入流中读取基本类型数据了
DataInputStream input = new DataInputStream(new FileInputStream("binary.data"));
int aByte = input.read();
int anInt = input.readInt();
float aFloat = input.readFloat();
double aDouble = input.readDouble();//etc.
input.close();
当你要读取的数据中包含了int,long,float,double这样的基本类型变量时,DataInputStream可以很方便地处理这些数据。
2.4 DataOutputStream
DataOutputStream可以往输出流中写入Java基本类型数据
DataOutputStream output = new DataOutputStream(new FileOutputStream("binary.data"));
output.write(45);
//byte data output.writeInt(4545);
//int data output.writeDouble(109.123);
//double data output.close();
其他方面与DataInputStream类似.
序列化与ObjectInputStream、ObjectOutputStream
Java IO中的序列化以及涉及到的流,主要包括ObjectInputStream和ObjectOutputStream。
3.1 Serializable
如果你希望类能够序列化和反序列化,必须实现Serializable接口,就像所展示的ObjectInputStream和ObjectOutputStream例子一样。
3.2 ObjectInputStream
ObjectInputStream能够让你从输入流中读取Java对象,而不需要每次读取一个字节。你可以把InputStream包装到ObjectInputStream中,然后就可以从中读取对象了。
ObjectInputStream input = new ObjectInputStream(new FileInputStream("object.data"));
MyClass object = (MyClass) input.readObject(); //etc.
input.close();
在这个例子中,你读取的对象必须是MyClass的一个实例,并且必须事先通过ObjectOutputStream序列化到“object.data”文件中。(译者注:ObjectInputStream和ObjectOutputStream还有许多read和write方法,比如readInt、writeLong等等,详细信息请查看官方文档)
在你序列化和反序列化一个对象之前,该对象的类必须实现了java.io.Serializable接口。
3.3 ObjectOutputStream
ObjectOutputStream能够让你把对象写入到输出流中,而不需要每次写入一个字节。你可以把OutputStream包装到ObjectOutputStream中,然后就可以把对象写入到该输出流中了。
ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream("object.data"));
MyClass object = new MyClass(); output.writeObject(object); //etc.
output.close();
例子中序列化的对象object现在可以从ObjectInputStream中读取了。
同样,在你序列化和反序列化一个对象之前,该对象的类必须实现了java.io.Serializable接口。
备注:文章参考
Java IO: 序列化与ObjectInputStream、ObjectOutputStream