参考:
http://blog.sina.com.cn/s/blog_9f233c070101ejrf.html
http://www.2cto.com/kf/201312/262036.html
http://blog.chinaunix.net/uid-20577907-id-3138084.html
http://blog.chinaunix.net/uid-20577907-id-3136982.html
api: http://docs.oracle.com/javase/7/docs/api/

什么是io流?

1.流的概念

流代表了数据的无结构化传递。按照流的方式进行输入输出,数据被当成无结构的字节序或字符序列。从流中取得数据的操作称为提取操作,而向流中添加数据的操作称为插入操作。用来进行输入输出操作的流就称为IO流。换句话说,IO流就是以流的方式进行输入输出。流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。流机制是JAVA及C++中的一个重要的机制,通过流能使我们能自由地控制包括文件,内存,IO设备等等中的数据的流向。 如:可以从文件输入流中获取数据,经处理后再通过网络输出流把数据输出到网络设备上;或利用对像输出流把一个程序中的对象输出到一个格式流文件中,并通过网络流对象将其输出到远程机器上,然后在远程机器上利用对象输入流将对象还原。 像这些机制是别的高级语言所不能比拟的。但要掌握好这些流对象,流的概念是很重要的。 流是一串连续不继的数据的集合,就像水管里的水流,在水管的一端一点一点地供水,而在水管的另一端看到的是一股连续不断的水流。数据写入程序可以是一段一段地向数据流管道中写入数据,这些数据段会按先向顺序形成一个长的数据流。对数据的读取程序来说,看不到数据流在写入时的分段情况,每次可以读取其中的任意长度的数据,但只能先读取前面的数据后,再读取后面的数据。不管写入时是将数据分多次写入,还是作为一个整体一次写入,读取时的效果都是完全一样的。

2.io流分类(http://www.2cto.com/kf/201312/262036.html

J2sdk所提供的所有流类位于Java.io包内,继承以下四种抽象流类,如图:

io流理解 java java中的io流知识总结_io流

1.按流的方向分为:输入流和输出流

将数据冲外存中读取到内存中的称为输入流,将数据从内存写入外存中的称为输出流。

输入流:程序从输入流读取数据源(read)。数据源包括外界(键盘、文件、网络…),即是将数据源读入到程序的通信通道
  输出流:程序向输出流写入数据(write)。将程序中的数据输出到外界(显示器、打印机、文件、网络…)的通信通道。

2.按流的数据单位不同分为:字节流和字符流

字符流:Reader Writer
字节流:InputStream(读数据)OutputStream(写数据)

3.按流的功能不同分为:节点流和处理流(过滤流)

节点流:从特定的地方读写的流类,例如:磁盘或一块内存区域。
 过滤流:使用节点流作为输入或输出。过滤流是使用一个已经存在的输入流或输出流连接创建的。

补充:

Java内用Unicode 编码存储字符,字符流处理类负责将外部的其他编码的字符流和java内Unicode 字符流之间的转换。而类InputStreamReader 和OutputStreamWriter处理字符流和字节流的转换。字符流(一次可以处理一个缓冲区)一次操作比字节流(一次一个字节)效率高。
字符流和字节流
    字符流的由来: 因为数据编码的不同,而有了对字符进行高效操作的流对象。本质其实就是基于字节流读取时,去查了指定的码表。字节流和字符流的区别:
    (1)读写单位不同:字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节。
    (2)处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据。
    (3)字节流在操作的时候本身是不会用到缓冲区的,是文件本身的直接操作的;而字符流在操作的时候下后是会用到缓冲区的,是通过缓冲区来操作文件,我们将在下面验证这一点。
    结论:优先选用字节流。首先因为硬盘上的所有文件都是以字节的形式进行传输或者保存的,包括图片等内容。但是字符只是在内存中才会形成的,所以在开发中,字节流使用广泛。

io流理解 java java中的io流知识总结_io流理解 java_02

java经常使用到的io流

System.out与System.in(标准输入,输出数据流)

java系统自带的标准数据流:java.lang.System

java.lang.System   
public final class System  extends Object{   
   static  PrintStream  err;//标准错误流(输出)  
   static  InputStream  in;//标准输入(键盘输入流)  
   static  PrintStream  out;//标准输出流(显示器输出流)  
}

注意:
(1)System类不能创建对象,只能直接使用它的三个静态成员。
(2)每当main方法被执行时,就自动生成上述三个对象。

标准输出流 System.out
System.out向标准输出设备输出数据,其数据类型为PrintStream(继承OutputStream)。

方法:

Void print(参数)
  Void println(参数)

例如:

try {
    InputStream input = new FileInputStream("d:\\test\\...");
    System.out.println("File opened...");
} catch (IOException e) {
   System.err.println(" File opening failed: ");
    e.printStackTrace();
}

标准输入流 System.in

System.in读取标准输入设备数据(从标准输入获取数据,一般是键盘),其数 据类型为InputStream。可以调用它的read方法来读取键盘数据。read方法见如下表格:

io流理解 java java中的io流知识总结_输入输出流_03

例如:

import java.io.*;  
public class StandardInputOutput {  
    public static void main(String args[]) {  
        int b;  
        try {  
            System.out.println("please Input:");  
            while ((b = System.in.read()) != -1) {  
                System.out.print((char) b);  
            }  
        } catch (IOException e) {  
            System.out.println(e.toString());  
        }  
    }  
}

Java I/O相关的包

java.nio是针对原java io所开发的一套新的io api接口。

Java NIO(New IO)是从Java 1.4版本开始引入的一个新的IO API,对比如下:

io流理解 java java中的io流知识总结_输入输出流_04

Java I/O相关流的类:

字符流:

io流理解 java java中的io流知识总结_io流理解 java_05


字节流:

io流理解 java java中的io流知识总结_io流_06

Java I/O相关File类

在Java语言的java.io包中,由File类提供了描述文件和目录的操作与管理方法。但File类不是InputStream、OutputStream或Reader、Writer的子类,因为它不负责数据的输入输出,而专门用来管理磁盘文件与目录。

作用:File类主要用于命名文件、查询文件属性和处理文件目录。

File类共提供了三个不同的构造函数,以不同的参数形式灵活地接收文件和目录名信息。构造函数:

io流理解 java java中的io流知识总结_java_07


一个对应于某磁盘文件或目录的File对象一经创建, 就可以通过调用它的方法来获得文件或目录的属性。

1)public boolean exists( ) 判断文件或目录是否存在

2)public boolean isFile( ) 判断是文件还是目录

3)public boolean isDirectory( ) 判断是文件还是目录

4)public String getName( ) 返回文件名或目录名

5)public String getPath( ) 返回文件或目录的路径。

6)public long length( ) 获取文件的长度

7)public String[ ] list ( ) 将目录中所有文件名保存在字符串数组中返回。

File类中还定义了一些对文件或目录进行管理、操作的方法,常用的方法有:

1) public boolean renameTo( File newFile ); 重命名文件

2) public void delete( ); 删除文件

3) public boolean mkdir( ); 创建目录

例子:

[java] view plain copy print?
import java.io.File;  
import java.io.IOException;  
public class TestFile {  
    public static void main(String args[]) throws IOException {  
        File dir = new File("\\root");  
        File f1 = new File(dir, "fileOne.txt");  
        File f2 = new File(dir, "fileTwo.java");  
        // 文件对象创建后,指定的文件或目录不一定物理上存在  
        if (!dir.exists())  
            dir.mkdir();  
        if (!f1.exists())  
            f1.createNewFile();  
        if (!f2.exists())  
            f2.createNewFile();  
        System.out.println("f1's AbsolutePath=  " + f1.getAbsolutePath());  
        System.out.println("f1 Canread=" + f1.canRead());  
        System.out.println("f1's len= " + f1.length());  
        String[] FL;  
        int count = 0;  
        FL = dir.list();  
        for (int i = 0; i < FL.length; i++) {  
            count++;  
            System.out.println(FL[i] + "is in \\root");  
        }  
        System.out.println("there are" + count + "file in //root");  
    }  

}

说明:File类的方法:
(1) exists()测试磁盘中指定的文件或目录是否存在
(2) mkdir()创建文件对象指定的目录(单层目录)
(3) createNewFile()创建文件对象指定的文件
(4) list()返回目录中所有文件名字符串

java.io包内的流

按I/O类型来总体分类:

1.   Memory        1)从/向内存数组读写数据: CharArrayReader、 CharArrayWriter、ByteArrayInputStream、ByteArrayOutputStream
                   2)从/向内存字符串读写数据 StringReader、StringWriter、StringBufferInputStream
2.  Pipe管道  实现管道的输入和输出(进程间通信): PipedReader、PipedWriter、PipedInputStream、PipedOutputStream
3.  File文件流。对文件进行读、写操作 :FileReader、FileWriter、FileInputStream、FileOutputStream
4.  ObjectSerialization 对象输入、输出 :ObjectInputStream、ObjectOutputStream
5.  DataConversion数据流 按基本数据类型读、写(处理的数据是Java的基本类型(如布尔型,字节,整数和浮点数)):DataInputStream、DataOutputStream
6. Printing 包含方便的打印方法 :PrintWriter、PrintStream
7. Buffering缓冲  在读入或写出时,对数据进行缓存,以减少I/O的次数:BufferedReader、BufferedWriter、BufferedInputStream、BufferedOutputStream
8.Filtering滤流,在数据进行读或写时进行过滤:FilterReader、FilterWriter、FilterInputStream、FilterOutputStream过
9. Concatenation合并输入 把多个输入流连接成一个输入流 :SequenceInputStream 
10.Counting计数在读入数据时对行记数:LineNumberReader、LineNumberInputStream
11. Peeking Ahead 通过缓存机制,进行预读 :PushbackReader、PushbackInputStream
12. Converting between Bytes and Characters 按照一定的编码/解码标准将字节流转换为字符流,或进行反向转换(Stream到Reader,Writer的转换类):InputStreamReader、OutputStreamWriter

按数据来源(去向)分类:

1、File(文件): FileInputStream, FileOutputStream, FileReader, FileWriter
2、byte[]:ByteArrayInputStream, ByteArrayOutputStream
3、Char[]: CharArrayReader, CharArrayWriter
4、String: StringBufferInputStream, StringReader, StringWriter
5、网络数据流:InputStream, OutputStream, Reader, Writer

1.java.io.InputStream类总结

InputStream —–字节输入流

InputStream 为字节输入流,它本身为一个抽象类,必须依靠其子类实现各种功能,此抽象类是表示字节输入流的所有类的超类。 继承自InputStream 的流都是向程序中输入数据的,且数据单位为字节(8bit);

InputStream是输入字节数据用的类,所以InputStream类提供了3种重载的read方法.Inputstream类中的常用方法:
  (1) public abstract int read( ):读取一个byte的数据,返回值是高位补0的int类型值。若返回值=-1说明没有读取到任何字节读取工作结束。
  (2) public int read(byte b[ ]):读取b.length个字节的数据放到b数组中。返回值是读取的字节数。该方法实际上是调用下一个方法实现的
  (3) public int read(byte b[ ], int off, int len):从输入流中最多读取len个字节的数据,存放到偏移量为off的b数组中。
  (4) public int available( ):返回输入流中可以读取的字节数。注意:若输入阻塞,当前线程将被挂起,如果InputStream对象调用这个方法的话,它只会返回0,这个方法必须由继承InputStream类的子类对象调用才有用,
  (5) public long skip(long n):忽略输入流中的n个字节,返回值是实际忽略的字节数, 跳过一些字节来读取
  (6) public int close( ) :我们在使用完后,必须对我们打开的流进行关闭.

2.java.io.OutputStream类总结

  OutputStream提供了3个write方法来做数据的输出,这个是和InputStream是相对应的。
  1. public void write(byte b[ ]):将参数b中的字节写到输出流。
  2. public void write(byte b[ ], int off, int len) :将参数b的从偏移量off开始的len个字节写到输出流。
  3. public abstract void write(int b) :先将int转换为byte类型,把低字节写入到输出流中。
  4. public void flush( ) : 将数据缓冲区中数据全部输出,并清空缓冲区。
  5. public void close( ) : 关闭输出流并释放与流相关的系统资源。
主要的子类:

1) ByteArrayOutputStream:把信息存入内存中的一个缓冲区中 
  2) FileOutputStream:把信息存入文件中 
  3) PipedOutputStream:实现了pipe的概念,主要在线程中使用 
  4) SequenceOutputStream:把多个OutStream合并为一个OutStream