IO/NIO — 输入/输出流
一、流的分类
-
按流的方向分,可以分为输入流和输出流(以程序运行所在内存角度划分)
-
按操作单元分,可以分为字节流和字符流(字节流1字节,字符流2字节)
-
按流的角色分,可以分为节点流和处理流
节点流:从/向特定的IO设备(磁盘、网络等)读写数据的流,也称低级流
处理流:对一个已存在的流进行连接或者
封装
,再实现数据读写功能
二、常用方法
1、InputStream 和 Reader
是所有输入流的抽象基类,所有实现 inputStream 和 Reader 的类,都有如下方法(其中Reader单元是 字符和char[],其他的都一样)
- read():从输入流中读取单个字节,返回所读取的字节数据
- read(byte[] b):从输入流中读取数组b长度个字节的数据,并将数据存储在字节数组
byte[]
中,返回实际读取的字节数 - read(byte[] b, int off, int len):从输入流最大读取len个字节的数据,并将数据存放到字节数组
byte[]
中,而且存放位置是从off
开始
例如,使用 FileInputStram读取文件:
public static void main(String[] args) throws IOException{
// 创建字节输入流
FileInputStream files = new FileInputStream("test.txt");
// 创建一个数组,批量读取
byte[] bt = new byte[1024];
// 用于保存实际读取的字节数
int readCount = 0;
while((readCount = files.read(bt) > 0){
// 打印读取一次的字节,转字符串
System.out.print(new String(bt, 0, readCount));
}
// 关闭资源
files.close();
}
2、OutputStream 和 Writer
是所有输出流的抽象基类,所有实现 OutputStream 和 Writer的类,都有如下方法
- write(int c):将指定字节输出到输出流中
- write(byte[] buf):将字节数组中的数据输出到指定输出流中
- write(byte[] buf, int off, int len):将字节数组从 off 开始,长度为 len的字节输出到输出流中
而且Writer
还可以用字符串代替数组,如下
- write(String str):将指定字符输出到输出流中
- write(String str, int off, int len):将字符数组从 off 开始,长度为 len的字符输出到输出流中
节点流实现文件复制:
public static void main(String[] args) throws IOException{
// 创建一个字节输入流,一个字节输出流
FileInputStream input = new FileInputStream("test.txt");
FileOutputStream output = new FileOutputStream("newTest.txt");
byte[] bt = new byte[64];
int readCount = 0;
while((readCount = input.read(bt)) > 0){
// 每读取一次,写入一次
output.write(bt, 0, readCount);
}
// 关闭资源
files.close();
}
三、处理流
可以隐藏底层设备上节点的差异,例如和I/O设备、文件的交互,前面两个例子都是节点流(直接以物理IO节点作为构造参数)
-
处理流和节点流的区别:处理流构造参数不是物理节点,而是流
例如:
缓冲流(
BufferedInputStream
、BufferedOutputStream
、BufferedReader
、BufferedWriter
) 对象流(
ObjectInputStream
、ObjectOutputStream
) 打印流(
PrintStream
、PrintWriter
)等等 -
缓冲流 BufferedReader 的使用
其他的缓冲流用法都差不多,先以流为参数构造
缓存实现文件复制:
public static void main(String[] args) throws IOException{ // 创建 BufferedReader bufr = new BufferedReader(new FileReader("test.txt")); BufferedWriter bufw = new BufferedWriter(new FileWriter("newTest.txt")); String line = null; // 一行一行的读取,读到末尾时,返回null while((line = buf.readLine()) != null){ bufw.write(line); // 将读取到的数据写入 bufw.newLine(); // 写一个行分隔符 bufw.flush(); // 冲洗流 } bufr.close(); bufw.close(); }
四、转换流
InputStreamReader
:将字节输入流转换成字符输入流OutputStreamWriter
:将字节输出流转换成字符输出流
// 获取键盘输入内容(键盘输入获取就是 System.in),获取的是字节,转换一下
InputStreamReader reader = new InputStreamReader(System.in);
// 再将 Reader 对象包装成 BufferedReader
BufferedReader br = new BufferedReader(reader);