★java的IO类以种类繁多著称,但它们也非常实用,对使用者来说最重要的是明白什么时候该用什么类。
•java.io.File既能代表一个特定文件的名称,也能代表一个目录下的一组文件。
•java.io.FilenameFilter接口是一种“目录过滤器”,用来过滤不符合规格的文件名。
public interface FilenameFilter{
boolean accept(File dir,String name);
}
•流:何为流?流是一种数据流动的抽象,任何有能力产出数据或者接受数据的对象都可以称为流。数据的输出端和输入端可以是不同的数据源,比如数据源可以是字节数组,String对象,文件,管道,Internet等,只要可以获得数据,当然,java对不同的数据源也有不同的类。
★InputSream:
InputStream是从设备到程序的输入字节流,代表程序从数据源获取数据,因为数据源的种类不同,所以有许多子类代表了不同的数据源:
①ByteArrayInputStream:从字节数组中获取数据,字节数组在内存中,所以等于是从内存缓存区中获取数据。
ByteArrayInputStream bs = new ByteArrayInputStream(new byte[]{1,2,3});
②StringBufferInputStream:从一个字符串获取数据。不过现在已经不建议使用(@Deprecated)。
StringBufferInputStream sb = new StringBufferInputStream("IO Study");
③FileInputStream:最常用的InputStream,从一个文件中获取数据。
FileInputStream file = new FileInputStream(new File("文件路径"));
④PipedInputStream:线程中通信使用。从另一个线程中获取数据。和PipedOutputStream配套使用。
PipedOutputStream out = new PipedOutputStream();
PipedInputStream in = new PipedInputStream();
out.connect(in);
//...
⑤SequenceInputStream:合并流,从2个或多个数据源获取数据,有两个构造器:
public SequenceInputStream(Enumeration<? extends InputStream> e);
public SequenceInputStream(InputStream s1, InputStream s2);
⑥FilterInputStream:“装饰器鼻祖”,前面的文章介绍过的装饰者模式。为其他的InputStream提供功能,以其他的InputStream作为构造器参数的InputStream。它的不同子类可以为InputStream提供不同的功能,比如缓存等。
protected FilterInputStream(InputStream in)
★OutputSream:代表了流要去往的地方,可能是一个字节数组,一个文件,或者是一个线程。
①ByteArrayOutputStream:代表了数据流向一个字节数组,也就是内存当中的缓冲区。你可以指定缓冲区的大小,也可以默认是32个字节。
//默认32字节
public ByteArrayOutputStream() {
this(32);
}
public ByteArrayOutputStream(int size) {
//指定字节数组的大小
buf = new byte[size];
}
②FileOutputStream:数据流向文件。
FileOutputStream fos = new FileOutputStream(new File("文件路径"));
③PipedOutputStream:一个线程的输出,可作为另一个线程的输入。
④FilterOutputStream:为其他的OutputStream提供功能,以其他的OutputStream作为构造器参数的OutputStream。它的不同子类可以为OutputStream提供不同的功能,比如缓存等。
public FilterOutputStream(OutputStream out);
★FilterInputStream和FilterOutputStream分别自InputStream和OutputStream派生而来,这两个类是装饰器的必要条件。
以下是一张IO家族的图片,writer和reader属于字符流,只是把字节处理变成了字节处理。
★为了更好的支持16位的Unicode字符,java引入了Reader和Writer继承树。尽管有一些场合必须使用面向字节,比如java.util.zip类库,但是还是应该尽量尝试使用Reader和Writer。
★Reader和Writer类继承结构思想和InputStream和OutputStream大致相同,但是需要注意两点:
①BufferedOutputStream和PrintStream是FilterOutputStream的子类,但是对应的BufferedWriter和PrintWriter并不是FilterWriter的子类。FilterWriter无任何子类,之所以它存在,只是为了看起来整齐一些,充当占位符的作用。
②当要使用readLine()这个函数,不要使用DataInputStream,应该使用BufferedReader()。除此之外还是应该尽量使用DataInputStream。
★InputStreamReader:把InputStream转换为Reader。
OutputStreamWriter:把OutputStream转换为Writer。
★独立于IO继承体系的类:RandomAccessFile。所以它并不支持装饰。
public RandomAccessFile(String name, String mode);
★System.in,System.out,System.err属于标准IO。
可以对它们进行重定向:
setIn(InputStream);
setOut(PrintStream);
setErr(PrintStream);
重定向操纵的是字节流,不是字符流。