字节流(常用)的继承关系:
1.InputStream和OutputStream (抽象类,所以以下都是对它的子类)
-
Input和Output都是对于程序来说的,input是从其他地方的数据读取到程序中,output是把程序中的数据存储在其他地方.
-
read和write方法都在执行时阻塞
-
read和write方法都可以读取一个或多个字节,但读取一个和读取多个字节不是调用了同一个native方法.(没有看源代码之前我以为读多个字节是用循环读入一个字节实现的)
-
InputStream:
-
int available()返回当前可读入的字节数量.可以避免阻塞的发生:
1int bytesAvailable = in.avaliable(); 2if(bytesAvailable > 0){ 3 byte[] data = new byte[bytesAvailable]; 4 in.read(data); 5}
-
-
OutputStream:
- close()和flush()方法都会冲刷输出流.有一些数据可能临时存储在缓冲区中等待以更大的包的形式传递,如果不冲刷输出流会出现数据丢失的现象!不关闭流是对系统资源的浪费!所以读取完数据一定要close.
2.ByteArrayInputStream和ByteArrayOutputStream
-
这两个类都是以内存中的一块buffer作为读取的对象,并且close方法无效,调用close后此类中的方法可以被调用,不会抛出异常.
-
ByteArrayInputStream(不常用):
-
构造方法:
1ByteArrayInputStream(byte[] buf); //Creates a ByteArrayInputStream so that it uses buf as its buffer array. 2ByteArrayInputStream(byte[] buf, int offset, int length); -
其他的方法和InputStream差不多.
-
-
ByteArrayOutputStream(常用作为buffer使用):
-
构造方法:
1ByteArrayOutputStream(); //buffer默认大小为32字节,并且buffer大小可以自动增长 2ByteArrayOutputStream(int size); -
reset()可将内部buffer的"指针"指向第一个字节,这样可以再用一次.
-
byte[] toByteArray和String toString()用于获取数据,其中toString还可以指定解码的字符集.
-
writeTo(OutputStream out)将buffer中的字节数组输出在out中,相当于调用 out.write(buf, 0, count).
-
2.FileInputStream和FileOutputStream
-
用于文件的读写,读写方式与父类一样,经常用于传入其他IO类的构造方法.
-
FileInputStream:
-
构造方法(常用):
1FileInputStream(File file); 2FileInputStream(String name);
-
-
FileOutputStream:
-
构造方法(常用):
1FileOutputStream(File file); 2FileOutputStream(File file, boolean append); 3FileOutputStream(String name); 4FileOutputStream(String name, boolean append);
-
2.FilterInputStream和FilterOutputStream
-
这两个类及其子类都需要一个InputStream或OutputStream为参数来构造,这是一种名为装饰(Decorator)的设计模式,它本身只是用传入的参数对象来处理数据,没有做装饰,只是为约束它的子类而写的.具体什么是装饰模式请参考:
-
装饰和代理模式的区别与联系请参考:
2.ObjectInputStream和ObjectOutputStream
-
这两个类都是用来对于对象的存取的,用于操作的对象要实现java.io.Serializable接口,此接口只用来标记没有方法需要实现.对于一个复杂的对象来说可能会有很多对象实例作为它的域,这时如果仅仅保存对象的引用是没用的,java中是用序列号(serial number)来标识对象,并将它保存至流中,如果对象之前被保存过,只需记录一下,因为序列号对于相同的对象是相等的,而不同的对象是不相等的(有相关的算法).这就是这种机制之所以称为对象序列化的原因.
-
ObjectInputStream:
-
构造方法:
1protected ObjectInputStream(); //提供给子类用的... 2ObjectInputStream(InputStream in); -
可以读取的类型包括基本类型和类(实现了Serializable接口).
-
String readUTF(),需要注意的是此处读取的是以修订版的UTF-8编码与标准的UTF-8不同,并且在前两个字节还会保存实际写出的字符长度.所以只在写用于JVM的字符串才用这个方法,对于其他场合应该使用writeChars方法.
-
-
ObjectOutputStream:
-
构造方法:
protected ObjectOutputStream(); //提供给子类用的... ObjectOutputStream(OutputStream out);
1 2
-
3.BufferedInputStream和BufferedOutputStream
-
有一个buffer缓冲(普通的IO类也有buffer缓冲,虽然我不知道默认的大小,但应该这个类的缓冲区会很大吧),可以降低硬盘或其他的东西频繁工作.因为方法过少,通常只是流的一个"包装".
-
BufferedInputStream:
-
构造方法:
1BufferedInputStream(InputStream in); 2BufferedInputStream(InputStream in, int size); //size指定缓冲区大小
-
-
BufferedOutputStream:
-
构造方法:
BufferedOutputStream(OutputStream out); BufferedOutputStream(OutputStream out, int size); //size指定缓冲区大小
1 2
-
3.DataInputStream和DataOutputStream
-
这两个类一般作为文件读写流的最后一个"包装".
-
DataInputStream:
-
构造方法:
DataOutputStream(OutputStream out); -
可以读取基本类型,一行和String(UTF-8修订版).
-
-
DataOutputStream:
-
构造方法:
DataOutputStream(OutputStream out);
1* 可以写出基本类型,chars和String(UTF-8修订版). 2 3
-
3.PrintStream
-
PrintStream输出字符串时可以指定编码,默认编码为系统默认编码.(DataOutputStream则不可以 )
-
不会抛出IO异常,用 checkError()检查是否发生错误.
-
构造方法:
1PrintStream(File file); 2PrintStream(File file, String csn) //csn==charsetname 3PrintStream(OutputStream out) 4PrintStream(OutputStream out, boolean autoFlush) 5PrintStream(OutputStream out, boolean autoFlush, String encoding) 6PrintStream(String fileName) 7PrintStream(String fileName, String csn) -
System.out正是PrintStream类型,它的方法无需赘言.
在实际应用时可能会经常用到嵌套的方式创建一个流对象,举个例子:
1DataInputStream dis=new DataInputStream( 2 new BufferedInputStream( 3 new FileInputStream("1.dat")));//这样就可以用DataInputStream的很多方法,而且还有缓冲区.
《java核心技术》卷二.
Java Platform Standard Edition 8 Documentation.