Java 中 的 IO 操作就是对字型节或字符型数据的读写。
一、IO 分类
1.按流的方向分类
输入流(InputStream、Reader):只能进行读操作。
输出流(OutputStream、Writer):只能进行写操作。
2.按流的类型分类
字节流(InputStream、OutputStream):以字节(8bit)为单位,可以处理任何类型的数据。
字符流(Reader、Writer):以字符为单位,字节流读取时,根据码表映射成字符。一次可能读多个字节。只能处理字符类型的数据。
二、IO 类使用
1.基类(抽象类:InputStream/Reader,OutputStream/Writer。其它 IO 操作类都是基于这些抽象类)
InputStream(输入字符流)
int read():从输入流中读取单个字节。返回所读取的字节数据(字节数据可直接转换为int类型)。
int read(byte[] b):从输入流中最多读取 b.length 个字节的数据,并将其存储在字节数组 b 中。返回实际读取的字节数。
int read(byte[] b, int off, int len);:从输入流中最多读取 len 个字节的数据,并将其存储在数组 b 中,放入数组 b 中时,并不是从数组起点开始,而是从 off 位置开始。返回实际读取的字节数。
int available():返回流中尚未读取的字节的数。
long skip(long n):跳过 n 个字节不读。返回实际跳过的字节数。
void mark(int readlimit):标记流的当前读取位置。
void reset():使流的读取位置恢复到最后一次调用 mark() 方法所标记的位置。
boolean markSupported():测试当前流是否支持 mark()/reset() 组合。
void close():关闭流,GC 无法释放 IO 资源,需手动关闭。
OutputStream(输出字符流)
void write(int b):往流中写一个字节 b。
void write(byte b[]):往流中写一个字节数组 b。
void write(byte b[], int off, int len):把字节数组 b 中从下标 off 开始,长度为 len 的字节写入到流中。
void flush():刷新流,输出所有被缓存的字节。某些流支持缓存功能,该方法将把缓存中所有内容强制输出到流中。
close()
Reader(输入字节流)
int read():从输入流中读取单个字符,返回所读取的字符数据(字符数据可直接转换为int类型)。
int read(char[] b)
int read(char[] b, int off, int len)
int read(java.nio.CharBuffer target)
boolean ready():判断此流是否可以读取
long skip(long n)
void mark(int readlimit)
void reset()
boolean markSupported()
void close()
Writer(输出字节流)
void write(int c):将(字节/字符)输出到输出流中。
void write(char cbuf[]):将(字节数组/字符数组)中的数据输出到指定输出流中。
void write(char cbuf[], int off, int len):将(字节数组/字符数组)中从 off 位置开始,长度为 len 的(字节/字符)输出到此 Writer。
void write(String str):将 str 字符串里包含的字符输出到此 Writer。
void write(String str, int off, int len):将 str 字符串里面从 off 位置开始,长度为 len 的字符输出到此 Writer。
Writer append(char c):将指定的字符追加到此 Writer。
Writer append(CharSequence csq)
Writer append(CharSequence csq, int start, int end)
void flush()
void close()
2.实现类
基于文件(FileInputStream/FileReader ,FileOutputStream/FileWriter)
//实现了 AutoCloseable 写在 try() 中可自动关闭流
try (FileInputStream fis = new FileInputStream("D:\\tmp\\123.txt")) {//字节数组
byte[] b = new byte[1024];//用于保存的实际字节数
int hasRead = 0;while ((hasRead = fis.read(b)) > 0) {
System.out.print(new String(b, 0, hasRead, "UTF-8"));
}
}catch(FileNotFoundException e) {
e.printStackTrace();
}catch(IOException e) {
e.printStackTrace();
}try (FileReader fr = new FileReader("D:\\tmp\\123.txt")) {//字符数组
char[] b = new char[1024];int hasRead = 0;while ((hasRead = fr.read(b)) > 0) {
System.out.print(new String(b, 0, hasRead));
}
}catch(IOException e) {
e.printStackTrace();
}//复制文件
try (FileInputStream fis = new FileInputStream("D:\\tmp\\123.txt");
FileOutputStream fos= new FileOutputStream("D:\\tmp\\456.txt")) {byte[] b = new byte[1024];int hasRead = 0;while ((hasRead = fis.read(b)) > 0) {
fos.write(b,0, hasRead);
}
}catch(FileNotFoundException e) {
e.printStackTrace();
}catch(IOException e) {
e.printStackTrace();
}//复制文件
try (FileReader fr = new FileReader("D:\\tmp\\123.txt");
FileWriter fw= new FileWriter("D:\\tmp\\456.txt")) {char[] b = new char[1024];int hasRead = 0;while ((hasRead = fr.read(b)) > 0) {
fw.write(b,0, hasRead);
}
}catch(FileNotFoundException e) {
e.printStackTrace();
}catch(IOException e) {
e.printStackTrace();
}
View Code
缓存流(BufferedInputStream/BufferedReader,BufferedOutputStream/BufferedWriter)。支持 mark
try (FileInputStream fis = new FileInputStream("D:\\tmp\\123.txt");
FileOutputStream fos= new FileOutputStream("D:\\tmp\\456.txt");
BufferedInputStream bis= newBufferedInputStream(fis);
BufferedOutputStream bos= newBufferedOutputStream(fos)) {byte[] b = new byte[1024];int hasRead = 0;while ((hasRead = bis.read(b)) > 0) {
bos.write(b,0, hasRead);
}
}catch(FileNotFoundException e) {
e.printStackTrace();
}catch(IOException e) {
e.printStackTrace();
}try (FileReader fr = new FileReader("D:\\tmp\\123.txt");
FileWriter fw= new FileWriter("D:\\tmp\\456.txt");
BufferedReader br= newBufferedReader(fr);
BufferedWriter bw= newBufferedWriter(fw)) {char[] b = new char[1024];int hasRead = 0;while ((hasRead = br.read(b)) > 0) {
bw.write(b,0, hasRead);
}
}catch(FileNotFoundException e) {
e.printStackTrace();
}catch(IOException e) {
e.printStackTrace();
}
View Code
转换流(InputStreamReader/OutputStreamWriter)。将字节流转为字符流
try (FileInputStream fis = new FileInputStream("D:\\tmp\\123.txt");
FileOutputStream fos= new FileOutputStream("D:\\tmp\\456.txt");
BufferedReader br= new BufferedReader(newInputStreamReader(fis));
BufferedWriter bw= new BufferedWriter(newOutputStreamWriter(fos))) {char[] b = new char[1024];int hasRead = 0;while ((hasRead = br.read(b)) > 0) {
bw.write(b,0, hasRead);
}
}catch(FileNotFoundException e) {
e.printStackTrace();
}catch(IOException e) {
e.printStackTrace();
}
View Code
对象流(ObjectInputStream/ObjectOutputStream)。用于序列化
三、IO 分类表
Java 输入/输出流体系中常用的流的分类表
分类字节输入流字节输出流字符输入流字符输出流
抽象基类
InputStream
OutputStream
Reader
Writer
访问文件
FileInputStream
FileOutputStream
FileReader
FileWriter
访问数组
ByteArrayInputStream
ByteArrayOutputStream
CharArrayReader
CharArrayWriter
访问管道
PipedInputStream
PipedOutputStream
PipedReader
PipedWriter
访问字符串
StringReader
StringWriter
缓冲流
BufferedInputStream
BufferedOutputStream
BufferedReader
BufferedWriter
转换流
InputStreamReader
OutputStreamWriter
对象流
ObjectInputStream
ObjectOutputStream
抽象基类
FilterInputStream
FilterOutputStream
FilterReader
FilterWriter
打印流
PrintStream
PrintWriter
推回输入流
PushbackInputStream
PushbackReader
特殊流
DataInputStream
DataOutputStream
表中 粗体字所标出的类代表节点流,必须直接与指定的物理节点关联。斜体字加下划线标出的类代表抽象基类,无法直接创建实例。
字节流的输入与输出对应图
字符流的输入与输出对应图