本文共 3829 字,大约阅读时间需要 12 分钟。
输入流 : 可以从其中读入一个字节序列的对象称做输入流。
输出流 : 可以向其中写入一个字节序列的对象称作输出流。 抽象类InputStream和OutPutStream构成了有层次结构的输入/输出(IO)类的基础。 因为面向字节的流不便于处理以Unicode形式存储的信息(Unicode是定长双字节),所以从抽象类Reader和Writer中继承出来专门用于处理Unicode字符的类构成了一个单独的层次结构。这些类拥有的读入和写出操作都是基于两字节的Unicode码元的,而不是基于单字节的字符。 1.1 读写字节 (1)InputStream类中有一个抽象方法abstract int read(),该方法将读入一个字节,并返回读入的字节,或者在入到输入源结尾时返回-1。在设计具体输入流类时,必须覆盖这个方法以提供适应的功能。FileInputStream类中这个方法从某个文件中读入一个字节,而System.in(InputStream的一个子类的预定以对象)是从键盘读入信息。 InputStream类还有若干个非抽象方法,它们可以读入一个字节数组,或者跳过大量的字节。这些方法都要调用抽象的read方法,因此各个子类只需覆盖read()这一个方法。 OutputStream类提供了一个类似的抽象方法abstract void write(int b),它可以向某个输出位置写出一个字节。 (2)read和write方法在执行时都将阻塞,直至字节确实被读入或写出。这就意味着如果流不能被立即访问(通常是因为网络连接忙),那么当前的线程将被阻塞。这使得在这个方法等待指定的流变为可用的这段时间,其他的线程就有机会去执行有用的工作。 (3)int available()方法使我们可以去检查当前可用于读入的字节数量,这样就可以得到不可能被阻塞的代码片段。也可以认为是一次全部读入
int bytesAvailable = in.available(); if(bytesAvailable>0){ byte[] data = new byte[bytesAvailable]; in.read(data); }
(4)当完成对流的读写时,应该通过调用close方法来关闭它。该方法会释放十分有限的系统资源,如果一个应用程序打开了过多的流而没有关闭他们,那么系统资源将被耗尽。
关闭一个输出流的同时也就是在清空用于该输出流的缓冲区:所有被临时置于缓冲区中,以便以更大的包的形式传递的字符在关闭输出流时都将被送出。特别是,如果不关闭文件,那么写出字节的最后一个包可能将永远也得不到传递。通过flush方法可以认为的清空这些流。 1.2 完整的流家族 (1)Java中包含各种流类型的类超过60个。主要分成处理字节和字符两个单独的层次结构。InputStream和OutputStream类可以读写单个的字节或字节数组,。想要读写字符串和数字,需要功能更强大子类。例如:DataInputStream和DataOutputStream可以以二进制格式读写所有的基本Java类型。ZipInputStream和ZipOutputStream可以以常见的ZIP压缩格式读写文件。 (2)对于Unicode文本,可以使用抽象类Reader和Writer的子类。Reader和Writer类的基本方法与InputStream和OutputStream中的方法类似。 abstract int read() abstract void write(byte[] b) read方法返回一个Unicode码元(作为一个在0 - 65535的整数),或者在碰到文件结尾时返回-1。write方法在调用时,要传递一个Unicode码元。 (3)Java SE 5.0引入了4个附加的接口:Closeable、Flushable、Readable和Appendable。 Closeable拥有方法 void close() throws IOException; Flushable拥有方法 void flush() throws IOException; Readable拥有方法 public int read(java.nio.CharBuffer cb) throws IOException; CharBuffer类拥有按顺序和随机的进行读写访问的方法,它表示一个内存中的缓冲区或者一个内存映像的文件。 Appendable拥有方法 Appendable append(CharSequence csq) throws IOException; //向此 Appendable 添加指定的字符序列。 Appendable append(CharSequence csq, int start, int end) throws IOException; //向此 Appendable 添加指定字符序列的子序列。 Appendable append(char c) throws IOException; //向此 Appendable 添加指定字符。 CharSequence接口描述了一个char值序列的基本属性,它是用String、CharBuffer、StringBuilder和StringBuffer来实现的。 InputStream、OutputStream、Reader和Writer都实行了Closeable接口,而OutputStream和Writer还实现了Flushable接口。只有Writer实现了Appendable接口 1.3 组合流过滤器 (1)FileInputStream和FileOutputStream可以提供磁盘文件的输入输出流 e.g.FileInputStream fis = new FileInputStream("file.txt"); byte b = (byte)fis.read();注意:因为所有java.io中的类都将相对路径解释为以用户工作目录开始,通过调用System.getProperty("user.dir")来获取 (2)与抽象类InputStream和OutputStream一样,这些类支持在字节级别上的读写,也就是说只能读写字节和字节数组。假设只有DataInputStream那么就只能读入数字类型,没有任何从文件中获取数据的方法。 针对这种情况Java使用了一种灵活的机制来分离这两种职责。某些流(例FileInputStream)可以从文件和其他更外部的位置上获取字节,而其他流(DataInputStream或PrintWriter)可以将字节组装到更有用的数据类型中。 e.g.从文件中读入数字,首先创建一个FileInputStream,然后传递给DataInputStream的构造器
FileInputStream fis = new FileInputStream("file.txt"); DataInputStream dis = new DataInputStream(fis); double num = dis.readDouble();
e.g.使用缓冲机制,并希望最终使用DataInputStream
DataInputStream dis = new DataInputStream(new BufferedInputStream(new FileInputStream("file.txt")));(3)PushbackInputStream : 多个流链接在一起时跟踪各个中介流(intermediate stream),比如当读入输入时,需要浏览下一个字节是否是想要的值。在读取终止字节后,代码片段可以“取消读取”该字节,这样,输入流上的下一个读取操作将会重新读取被推回的字节。 e.g.推回(push back)取消读取
PushbackInputStream pis = new PushbackInputStream(new BufferedInputStream(new FileInputStream("file.txt")));//创建PushbackInputStream int b = pis.read(); //预读下一个字节 if(((char)b) != '<'){ pis.unread(b); //并非所期望的值时,将其退回 }
e.g.可推回输入流读入数字
DataInputStream dis = new DataInputStream(new PushbackInputStream (new BufferedInputStream(new FileInputStream("file.txt"))));
e.g.读取ZIP文件
ZipInputStream zis = new ZipInputStream(new FileInputStream("file.zip")); DataInputStream dis = new DataInputStream(zis);
转载地址:http://exyci.baihongyu.com/