IO流的分类
· 根据处理数据类型的不同分为:字符流和字节流
· 根据数据流向不同分为:输入流和输出流
· 按数据来源(去向)分类:
1、File(文件): FileInputStream, FileOutputStream, FileReader, FileWriter
2、byte[]:ByteArrayInputStream, ByteArrayOutputStream
3、Char[]: CharArrayReader,CharArrayWriter
4、String:StringBufferInputStream, StringReader, StringWriter
5、网络数据流:InputStream,OutputStream, Reader, Writer
字符流和字节流
流序列中的数据既可以是未经加工的原始二进制数据,也可以是经一定编码处理后符合某种格式规定的特定数据。因此Java中的流分为两种:
1) 字节流:数据流中最小的数据单元是字节
2) 字符流:数据流中最小的数据单元是字符, Java中的字符是Unicode编码,一个字符占用两个字节。
字符流的由来: Java中字符是采用Unicode标准,一个字符是16位,即一个字符使用两个字节来表示。为此,JAVA中引入了处理字符的流。因为数据编码的不同,而有了对字符进行高效操作的流对象。本质其实就是基于字节流读取时,去查了指定的码表。
字节流和字符流的区别:(详细可以参见http://blog.csdn.net/qq_25184739/article/details/51203733)
字节流没有缓冲区,是直接输出的,而字符流是输出到缓冲区的。因此在输出时,字节流不调用colse()方法时,信息已经输出了,而字符流只有在调用close()方法关闭缓冲区时,信息才输出。要想字符流在未关闭时输出信息,则需要手动调用flush()方法。
· 读写单位不同:字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节。
· 处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据。
结论:只要是处理纯文本数据,就优先考虑使用字符流。除此之外都使用字节流。
字符流与字节流转换
转换流的特点:
1. 其是字符流和字节流之间的桥梁
2. 可对读取到的字节数据经过指定编码转换成字符
3. 可对读取到的字符数据经过指定编码转换成字节
何时使用转换流?
1. 当字节和字符之间有转换动作时;
2. 流操作的数据需要编码或解码时。
具体的对象体现:
转换流:在IO中还存在一类是转换流,将字节流转换为字符流,同时可以将字符流转化为字节流。
1. InputStreamReader:字节到字符的桥梁
2. OutputStreamWriter:字符到字节的桥梁
OutputStreamWriter(OutStreamout):将字节流以字符流输出。
InputStreamReader(InputStream in):将字节流以字符流输入。
这两个流对象是字符体系中的成员,它们有转换作用,本身又是字符流,所以在构造的时候需要传入字节流对象进来。
1.输入字节流InputStream
1. InputStream是所有的输入字节流的父类,它是一个抽象类。
2. ByteArrayInputStream、StringBufferInputStream、FileInputStream是三种基本的介质流,它们分别从Byte数组、StringBuffer、和本地文件中读取数据。
3. PipedInputStream是从与其它线程共用的管道中读取数据.
4. ObjectInputStream和所有FilterInputStream的子类都是装饰流(装饰器模式的主角)。
InputStream中的三个基本的读方法
abstract int read() :读取一个字节数据,并返回读到的数据,如果返回-1,表示读到了输入流的末尾。
int read(byte[] b) :将数据读入一个字节数组,同时返回实际读取的字节数。如果返回-1,表示读到了输入流的末尾。
int read(byte[]?b, int off, int len) :将数据读入一个字节数组,同时返回实际读取的字节数。如果返回-1,表示读到了输入流的末尾。off指定在数组b中存放数据的起始偏移位置;len指定读取的最大字节数。
流结束的判断:方法read()的返回值为-1时;readLine()的返回值为null时。
2.输出字节流OutputStream
1. OutputStream是所有的输出字节流的父类,它是一个抽象类。
2. ByteArrayOutputStream、FileOutputStream是两种基本的介质流,它们分别向Byte数组、和本地文件中写入数据。PipedOutputStream是向与其它线程共用的管道中写入数据。
3. ObjectOutputStream和所有FilterOutputStream的子类都是装饰流。
outputStream中的三个基本的写方法
abstract void write(int?b):往输出流中写入一个字节。
void write(byte[]?b) :往输出流中写入数组b中的所有字节。
void write(byte[]?b, int?off, int?len) :往输出流中写入数组b中从偏移量off开始的len个字节的数。
void flush() :刷新输出流,强制缓冲区中的输出字节被写出。
void close() :关闭输出流,释放和这个流相关的系统资源。注:所有流都应该在结束时释放。
3.字符输入流Reader
1. Reader是所有的输入字符流的父类,它是一个抽象类。
2. CharReader、StringReader是两种基本的介质流,它们分别将Char数组、String中读取数据。PipedReader是从与其它线程共用的管道中读取数据。
3. BufferedReader很明显就是一个装饰器,它和其子类负责装饰其它Reader对象。
主要方法:
(1) public int read() throws IOException; //读取一个字符,返回值为读取的字符
(2) public int read(char cbuf[]) throws IOException; /*读取一系列字符到数组cbuf[]中,返回值为实际读取的字符的数量*/
(3) public abstract int read(char cbuf[],int off,int len) throws IOException;
/*读取len个字符,从数组cbuf[]的下标off处开始存放,返回值为实际读取的字符数量,该方法必须由子类实现*/
4.字符输出流Writer
1. Writer是所有的输出字符流的父类,它是一个抽象类。
2. CharArrayWriter、StringWriter是两种基本的介质流,它们分别向Char数组、String中写入数据。PipedWriter是向与其它线程共用的管道中写入数据,
3. BufferedWriter是一个装饰器为Writer提供缓冲功能。
主要方法:
(1) public void write(int c) throws IOException; //将整型值c的低16位写入输出流
(2) public void write(char cbuf[]) throws IOException; //将字符数组cbuf[]写入输出流
(3) public abstract void write(char cbuf[],int off,int len) throws IOException; //将字符数组cbuf[]中的从索引为off的位置处开始的len个字符写入输出流
(4) public void write(String str) throws IOException; //将字符串str中的字符写入输出流
(5) public void write(String str,int off,int len) throws IOException; //将字符串str 中从索引off开始处的len个字符写入输出流
8.非流式文件类--File类
File类是Object的直接子类,同时它继承了Comparable接口可以进行数组的排序。File类共提供了三个不同的构造函数,以不同的参数形式灵活地接收文件和目录名信息。
构造函数:
1)File (String pathname)
例:File f1=new File("FileTest1.txt"); //创建文件对象f1,f1所指的文件是在当前目录下创建的FileTest1.txt
2)File (String parent , String child)
例:File f2=new File(“D:\\dir1","FileTest2.txt") ;// 注意:D:\\dir1目录事先必须存在,否则异常
3)File (File parent , String child)
例:File f4=new File("\\dir3");
File f5=new File(f4,"FileTest5.txt"); //在如果 \\dir3目录不存在使用f4.mkdir()先创建
一个对应于某磁盘文件或目录的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( ); 创建目录
9.RandomAccessFile类
1. 该对象只能操作文件,所以构造函数接收两种类型的参数:a.字符串文件路径;b.File对象。
2. 该对象既可以对文件进行读操作,也能进行写操作,在进行对象实例化时可指定操作模式(r,rw)
10、System类对IO的支持,
Java语言系统预定了3个可以直接使用的流对象,分别是:
System.in(标准输入),通常代表键盘输入。
System.out(标准输出):通常写往显示器。
System.err(标准错误输出):通常写往显示器。
注意:
(1)System类不能创建对象,只能直接使用它的三个静态成员。
(2)每当main方法被执行时,就自动生成上述三个对象。
1) 标准输出流 System.out
System.out向标准输出设备输出数据,其数据类型为PrintStream。方法:
Void print(参数)
Void println(参数)
2)标准输入流 System.in
System.in读取标准输入设备数据(从标准输入获取数据,一般是键盘),其数 据类型为InputStream。方法:
int read() //返回ASCII码。若,返回值=-1,说明没有读取到任何字节读取工作结束。
int read(byte[] b)//读入多个字节到缓冲区b中返回值是读入的字节数
3)标准错误流
System.err输出标准错误,其数据类型为PrintStream。可查阅API获得详细说明。
另外
标准输出通过System.out调用println方法输出参数并换行,而print方法输出参数但不换行。println或print方法都通 过重载实现了输出基本数据类型的多个方法,包括输出参数类型为boolean、char、int、long、float和double。同时,也重载实现 了输出参数类型为char[]、String和Object的方法。其中,print(Object)和println(Object)方法在运行时将调 用参数Object的toString方法。
附加:
IOException异常类的子类
1.public class EOFException : 非正常到达文件尾或输入流尾时,抛出这种类型的异常。
2.public class FileNotFoundException: 当文件找不到时,抛出的异常。
3.public class InterruptedIOException: 当I/O操作被中断时,抛出这种类型的异常。