1.Java的IO流
Java的IO流(Stream)是实现输入/输出的基础,Java中把不同的输入/输出源(命令行、文件、网络等)抽象表述为 “流”,通过流的方式允许Java程序使用相同的方式来访问不同的输入/输出源。
2.流的分类
(1)按照“流向”,可以分输入流和输出流
- 输入流:只能从流中读取数据,以InputStream和Reader作为基类
- 输出流:只能向流中写数据,以OutputStream和Writer作为基类
(2)按照流操作的最小数据单元,可以分为
字节流和字符流
- 字节流:最小数据单元是8位的字节,以InputStream和OutputStream作为基类
- 字符流:最小数据单元是16位的字符,以Reader和Writer作为基类
(3)按照流的角色分,可以分为
节点流和处理流
- 节点流:可以从/向一个特定的IO设备(如磁盘\网络)读写数据的流,称为节点流,也叫低级流。
- 处理流:用于对一个已存在的流进行连接或者封装,通过封装后的流来实现数据读写,也叫高级流。
使用相同的处理流来包装不同的节点流,程序就可以使用相同的代码,来读写不同的数据源。
3.IO流的基类
(1)输入的基类:InputStream和Reader
InputStream和Reader的使用方法基本一致,只是前者(字节流)读取的基本单元是一个字节,后者读取的基本单元是字符。
InputStream的主要方法:
int read();从输入流中读取一个字节,并返回这个字节;
int read(byte[] b);从输入流中读取最多b.length个字节,放入b中,并返回读取的数量.
int read(byte[] b, int off, int len);从输入流中读取最多len个字节,从off位置开始读取,放入b中,返回读取的字节数.
Reader的主要方法:
int read();从输入流中读取一个字符,并返回
int
read(char[] cbuf);
从输入流中读取最多cbuf.length个字符,放入cbuf中,并返回读取的数量
int read(char[] cbuf, int off, int len)
;从输入流中读取最多len个字符,从off位置开始读取,放入cbuf中,返回读取的字符数量.
InputStream和Reader 提供移动指针的方法:
void mark(int readAheadLimit) 在指针的当前位置设置一个标记;
boolean
markSupported()
;判断输入流是否支持标记;
voidreset() 将指针重新定位到上一次的标记位置;
long
skip(long n)
指针向前移动n个字节/字符
一个FileInputStream示例,InputStream是抽象类不能创建实例,所以使用FileInputStream(InputStream的一个实现),Reader用法与InputStream基本一致。
package com.blueinfo.io;
import java.io.InputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class FileInputStreamTest {
public static void main(String[] args) {
InputStream fis = null;
try {
fis = new FileInputStream("E:\\app.log");
byte[] buf = new byte[1024];
int read = 0;
while((read=fis.read(buf)) > 0 ){
System.out.print(new String(buf,0,read));
}
} catch (FileNotFoundException e) {
System.out.println("cannot find file");
} catch (IOException e) {
System.out.println("file read error");
}
finally{
if(fis != null)
try {
fis.close();
} catch (IOException e) {
System.out.println("file close error");
}
}
}
}
(2)输出的基类:OutputStream和Writer
两者的使用也基本一致。
OutputStream的主要方法:
void write(int b);将b(字节的值)输出到输出流。
void write(byte[] b) ;将字节数组b输出到流。
void write(byte[] b, int off, int len);将数组中从位置off开始的值输出到流。
Writer的主要方法:
void write(int b);将b(字符的值)输出到输出流。
void write(char[] b) ;将字符数组b输出到流。
void write(char[] b, int off, int len);将数组中从位置off开始的值输出到流。
FileWriter示例:
package com.blueinfo.io;
import java.io.FileWriter;
import java.io.IOException;
public class FileWriterTest
{
public static void main(String[] args) throws IOException
{
FileWriter fw = null;
try
{
//创建字符输出流
fw = new FileWriter("test.txt");
fw.write(48);//字符 “0“
fw.write("wahaha\r\n");
}
catch (IOException ioe)
{
ioe.printStackTrace();
}
finally
{
//使用finally块来关闭文件输出流
if (fw != null)
{
fw.close();
}
}
}
}
4.IO流的体系
(1)InputStream体系
- ByteArrayInputStream:允许将内存的缓冲区当做InputStream使用。数据源:字节数组
- StringBufferInputStream:将String转换成InputStream。数据源:字符串
- FileInputStream:用于从文件中读取信息。数据源:文件
- PipedInputStream:产生用于写入相关PipedOutputStream的数据,实现管道化概念。数据源:管道
- SequenceInputStream:将两个或多个InputStream转化成一个InputStream
- FilterInputStream:抽象类,作为装饰器的接口。其子类实现为上述InputStream提供其他有用功能
(2)OutputStream体系
- ByteArrayOutputStream:在内存中创建缓冲区。所有送往“流”的数据都要放置在此缓冲区
- FileOutputStream:向文件写数据
- PipedOutputStream:任何写入其中的信息都会自动作为相关PipedInputStream的输入。
- FilterOutputStream:抽象类,作为装饰器的接口。为其它OutputStream提供有用功能。
(3)FilterInputStream体系(处理流)
实现FilterInputStream的类,通过装饰(节点)输入流,为“流”添加多种不同的组合功能。
- DataInputStream:与DataOutputStream搭配使用,可以按照可移植方式从流读取基本的数据类型(int,char,long等)
- BufferedInputStream:使用它可以防止每次读取时都得惊醒实际读操作
- LineNumberInputStream:可跟踪输入中的行号;getLineNumber();setLineNumber(int)
- PushbackInputStream:具有“能弹出一个字节的缓冲区”。因此可以将读到的最后一个字符回退。
(4)FilterOutputStream体系(处理流)
- DataOutputStream:与DataInputStream对应。可以按照可移植性方式写入基本类型(int,char,long等)
- PrintStream:用于产生格式化输出
- BufferedOutputStream:避免每次发送数据都要进行实际的写操作。flush()可以清空缓冲区
(5)Reader和Writer
Reader和Writer的加入,主要是为了国际化,Reader和Writer的继承体系和InputStram、OutputStream几乎一致,对应的类功能也相似。
节点流IO对应关系如下
InputStream | Reader |
无 | 适配器:InputStreamReader |
OutputStream | Writer |
无 | 适配器:OutputStreamWriter |
FileInputStream | FileReader |
FileOutputStream | FileWriter |
StringBufferInputStream(已弃用) | StringReader |
无 | StringWriter |
ByteArrayInputStream | CharArrayReader |
ByteArrayOutputStream | CharArrayWriter |
PipedInputStream | PipedReader |
PipedOutputStream | PipedWriter |
从表中看出新的IO体系,有着旧的IO体系几乎所有功能,但是在某些特定场合,必须用到面向字节Stream体系。所以应该尽量使用Reader和Writer提供天然的unicode操作,在特定场合使用Stream体系。
处理流的对应关系如下:
FilterInputStream | FilterReader |
FilterOutputStream | FilerWriter |
BufferedInputStream | BufferedReader(也有readLine()) |
BufferedOutputStream | BufferedWriter |
DataInputStream | 使用DataInputStream(需要readLine时使用BufferedReader) |
PrintStream | PrintWriter |
LineNumberInputStream(已弃用) | LineNumberReader |
StreamTokenizer | StreamTokennizer |
PushbackInputStream | PushbackReader |