定义
JavaIO流,是一种计算机用语。主要是用于处理数据的传输。
背景
I/O 流众多,在学习I/O流时,流与流之间关系理不清楚,什么场景下该选择使用什么样的流?成为了难点,因此,文本根据笔者的学习情况,梳理了常用的几种流
流的分类
按方向划分:
按处理的数据单位划分:
按功能划分:
四大抽象类
类定义 | 说明 |
---|
InputStream | 字节输入流,特点:凡是继承它的子类,类命名均以 InputStream 结尾,都是字节输入流 |
OutputStream | 字节输出流,特点:凡是继承它的子类,类命名均以 OutputStream 结尾,都是字节输出流 |
Reader | 字符输入流,特点:凡是继承它的子类,类命名均以 Reader 结尾 ,都是字符输入流 |
Writer | 字符输出流,特点:凡是继承它的子类,类命名均以 Writer 结尾,都是字符输出流 |
生活场景类比计算机输入输出流操作
抽水机抽水到水塔的A区:相当于输入流 InputStram
水塔对水进行消毒、过滤、净化后装入水塔B区:相对于对输入流里的数据写入到输出流
水塔将B区的净化水供给到居民家里:相当于将输出流进行输出
![在这里插入图片描述](https://img-blog.csdnimg.cn/85f754b1612d46d7bf3b2ee0934be5f5.png)
浅谈文件拷贝过程内存中的对象
![在这里插入图片描述](https://img-blog.csdnimg.cn/0cd626acd4da4f03995f4a06e8b2cfb8.png)
常用流说明
字节流
FileInputStream 对文件操作的字节输入流
构造器 | 方法说明 |
---|
FileInputStream(File file) | 有参构造器,传入 File 对象 |
FileInputStream(String name) | 有参构造器,传入文件的路径(含文件名) |
返回类型 | 方法 | 方法说明 |
---|
int | read() | 从该文件字节输入流中读取 下一个字节,并返回 该字节 对应的 整型数值,且游标自动指向下一个字节的位置 |
int | read(byte[] b) | 从该文件字节输入流读取最多 b.length 个字节的数据放入 字节数组b,并返回读取到的字节个数 |
int | read(byte[] b, int off, int len) | 从该文件字节输入流读取最多 len 个字节的数据放入 字节数组b,并返回读取到的字节个数 |
void | close() | 关闭此文件字节输入流并释放与流相关联的任何系统资源 |
package com.wei.java.basic.io;
import java.io.FileInputStream;
public class FileInputStream_my {
public static void main(String[] args) {
String filePath = "D:\\IdeaProjects\\my-study\\java-basic\\java-basic-begin\\src\\main\\resources\\io\\text_01.txt";
try (
FileInputStream fis = new FileInputStream(filePath);
) {
int byteInt = fis.read();
System.out.println(byteInt +" -> " + (char)byteInt);
byte[] bytes = new byte[2];
int len;
while ((len = fis.read(bytes)) != -1){
System.out.print(new String(bytes));
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
FileOutputStream 对文件操作的字节输出流
构造器 | 方法说明 |
---|
FileOutputStream(File file) | 有参构造器,传入 File 对象,创建文件输出流以写入到指定的 File对象表示的文件 |
FileOutputStream(File file, boolean append) | 有参构造器,传入 File 对象,创建文件输出流以写入到指定的 File对象表示的文件,append参数控制覆盖或追加数据到文件,true-追加,false-覆盖,默认false |
FileOutputStream(String name) | 有参构造器,传入文件的路径+文件名,将数据输出到指定的文件 |
FileOutputStream(String name, boolean append) | 有参构造器,传入文件的路径+文件名,将数据输出到指定的文件,append参数控制覆盖或追加数据到文件,true-追加,false-覆盖,默认false |
返回类型 | 方法 | 方法说明 |
---|
void | write(int b) | 将一个字节 的 整型数字,写入该文件字节输出流 |
void | write(byte[] b) | 将 b.length 个字节从 字节数组b 写入该文件字节输出流 |
void | write(byte[] b, int off, int len) | 将 字节数组b中,从 偏移量off 开始的 len个字节 数据,写入到该文件字节输出流 |
void | close() | 关闭此文件字节输出流并释放与流相关联的任何系统资源,不需要close(),数据也会输出到磁盘 |
package com.wei.java.basic.io;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class FileOutputStream_my {
public static void main(String[] args) {
String filePath = "D:\\IdeaProjects\\my-study\\java-basic\\java-basic-begin\\src\\main\\resources\\io\\text_01.txt";
String outFilePath = "D:\\IdeaProjects\\my-study\\java-basic\\java-basic-begin\\src\\main\\resources\\io\\out_01.txt";
try (
FileInputStream fis = new FileInputStream(filePath);
FileOutputStream fos = new FileOutputStream(outFilePath);
) {
byte[] bytes = new byte[2];
int len;
while ((len = fis.read(bytes)) != -1) {
fos.write(bytes, 0, len);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
ByteArrayInputStream 对字节数组操作的字节输入流
构造器 | 方法说明 |
---|
ByteArrayInputStream(byte[] buf) | 有参构造, 传入字节数组 |
返回类型 | 方法 | 方法说明 |
---|
int | read() | 从该字节数组输入流中读取 下一个字节,并返回 该字节 对应的 整型数值 |
int | read(byte[] b) | 从该字节数组输入流读取最多 b.length 个字节的数据放入 字节数组b,并返回读取到的字节个数 |
int | read(byte[] b, int off, int len) | 从该字节数组输入流读取最多 len 个字节的数据放入 字节数组b,并返回读取到的字节个数 |
void | close() | 关闭 ByteArrayInputStream没有任何效果,该流中的方法仍可以在流关闭后调用,而不生成IOException |
package com.wei.java.basic.io;
import java.io.ByteArrayInputStream;
import java.io.IOException;
public class ByteArrayInputStream_my {
public static void main(String[] args) throws IOException {
byte[] bytes = "wddd".getBytes();
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
int byteInt = bais.read();
System.out.println((char)byteInt);
bais.close();
int byteInt2 = bais.read();
System.out.println((char)byteInt2);
byte[] buff = new byte[2];
int read = bais.read(buff);
System.out.println(new String(buff));
}
}
ByteArrayOutputStream 对字节数组操作的字节输出流
构造器 | 方法说明 |
---|
ByteArrayOutputStream() | 无参构造器 |
返回类型 | 方法 | 方法说明 |
---|
void | write(int b) | 将一个字节 的 整型数字,写入该字节数组输出流 |
void | write(byte[] b, int off, int len) | 将 字节数组b中,从 偏移量off 开始的 len个字节 数据,写入到该字节数组输出流 |
byte[] | toByteArray() | 将字节数组输出流中的数据,转为新的字节数组,并返回该新的字节数组的完整数据 |
String | toString(String charsetName) | 将字节数组输出流中的数据转换为字符串,并指定编码类型 |
void | close() | 关闭 ByteArrayOutputStream 没有任何效果,该流中的方法可以在流关闭后调用,而不生成IOException |
package com.wei.java.basic.io;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
public class ByteArrayOutputStream_my {
public static void main(String[] args) throws IOException {
byte[] bytes = "qwertyuiopa我的观点".getBytes();
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int byteInt = bais.read();
System.out.println((char) byteInt);
bais.close();
byte[] buff = new byte[2];
int len;
while ((len = bais.read(buff)) != -1) {
baos.write(buff, 0, len);
}
baos.close();
baos.flush();
byte[] resultBytes = baos.toByteArray();
System.out.println(new String(resultBytes));
String resultStr = baos.toString("utf-8");
System.out.println(resultStr);
}
}
BufferedInputStream 带缓冲区的字节输入流
构造器 | 方法说明 |
---|
BufferedInputStream(InputStream in) | 有参构造器,传入 InputStream 对象 |
返回类型 | 方法 | 方法说明 |
---|
int | read() | 从该带缓冲区的字节输入流中读取 下一个字节,并返回 该字节 对应的 整型数值 |
int | read(byte[] b) | 从该带缓冲区的字节输入流读取最多 b.length 个字节的数据放入 字节数组b,并返回读取到的字节个数 |
int | read(byte[] b, int off, int len) | 从该带缓冲区的字节输入流读取最多 len 个字节的数据放入 字节数组b,并返回读取到的字节个数 |
void | close() | 关闭此带缓冲区的字节输入流并释放与流相关联的任何系统资源 |
package com.wei.java.basic.io;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
public class BufferedInputStream_my {
public static void main(String[] args) {
String filePath = "D:\\IdeaProjects\\my-study\\java-basic\\java-basic-begin\\src\\main\\resources\\io\\text_01.txt";
try (
FileInputStream fis = new FileInputStream(filePath);
BufferedInputStream bis = new BufferedInputStream(fis);
) {
int byteInt = bis.read();
System.out.println(byteInt +" -> " + (char)byteInt);
byte[] temp = new byte[3];
int fisReadByteInt = fis.read(temp);
System.out.println(fisReadByteInt);
byte[] bytes = new byte[2];
int len;
while ((len = bis.read(bytes)) != -1){
System.out.print(new String(bytes));
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
BufferedOutputStream 带缓冲区的字节输出流
构造器 | 方法说明 |
---|
BufferedOutputStream(OutputStream out) | 有参构造器,传入 OutputStream 对象 |
返回类型 | 方法 | 方法说明 |
---|
void | write(int b) | 将一个字节 的 整型数字,写入该带缓冲区的字节输出流 |
void | write(byte[] b) | 将 b.length 个字节从 字节数组b 写入该带缓冲区的字节输出流 |
void | write(byte[] b, int off, int len) | 将 字节数组b中,从 偏移量off 开始的 len个字节 数据,写入到该带缓冲区的字节输出流 |
void | close() | 关闭此带缓冲区的字节输出流并释放与流相关联的任何系统资源,只有 close() 后,数据才会真正写到磁盘 |
package com.wei.java.basic.io;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class BufferedOutputStream_my {
public static void main(String[] args) {
String filePath = "D:\\IdeaProjects\\my-study\\java-basic\\java-basic-begin\\src\\main\\resources\\io\\text_01.txt";
String outFilePath = "D:\\IdeaProjects\\my-study\\java-basic\\java-basic-begin\\src\\main\\resources\\io\\out_01.txt";
try (
FileInputStream fis = new FileInputStream(filePath);
BufferedInputStream bis = new BufferedInputStream(fis);
FileOutputStream fos = new FileOutputStream(outFilePath);
) {
BufferedOutputStream bos = new BufferedOutputStream(fos);
byte[] bytes = new byte[2];
int len;
while ((len = bis.read(bytes)) != -1) {
bos.write(bytes, 0, len);
}
bos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
ObjectInputStream 对对象操作的字节输入流、ObjectInputStream 对对象操作的字节输出流
- 构造方法
- 常用方法
用得少,主要用于序列化与反序列化
字符流
FileReader 对文件操作的字符输入流
构造器 | 方法说明 |
---|
FileReader(File file) | 有参构造,传入 File 对象 |
FileReader(String fileName) | 有参构造,传入文件路径(含文件名) |
返回类型 | 方法 | 方法说明 |
---|
int | read() | 从该字符输入流中读取 下一个字符,并返回 该字符 对应的 整型数值 |
int | read(char[] cbuf) | 从该字符输入流读取最多 cbuf.length 个字符的数据放入 字符数组cbuf,并返回读取到的字符个数 |
int | read(char[] cbuf, int offset, int length) | 从该字符输入流读取最多 length 个字节的数据放入 字符数组cbuf,并返回读取到的字符个数 |
void | close() | 关闭流并释放与之相关联的任何系统资源 |
package com.wei.java.basic.io;
import java.io.FileReader;
import java.io.IOException;
public class FileReader_my {
public static void main(String[] args) throws Exception {
String filePath = "D:\\IdeaProjects\\my-study\\java-basic\\java-basic-begin\\src\\main\\resources\\io\\text_01.txt";
try (
FileReader fr = new FileReader(filePath);
) {
int charInt = fr.read();
System.out.println((char) charInt);
char[] bytes = new char[2];
int len;
while ((len = fr.read(bytes)) != -1) {
System.out.print(new String(bytes));
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
FileWriter 对文件操作的字符输出流
构造器 | 方法说明 |
---|
FileWriter(File file) | 有参构造,传入 File 对象,给一个File对象构造一个FileWriter对象。 |
FileWriter(File file, boolean append) | |
FileWriter(String fileName) | 有参构造,传入文件路径(含文件名) |
FileWriter(String fileName, boolean append) | 有参构造,传入文件路径(含文件名),append 设置是否追加写入数据,true-追加,false-覆盖,默认false |
返回类型 | 方法 | 方法说明 |
---|
void | write(int c) | 写一个字符 |
void | write(char[] cbuf, int off, int len) | 将 字符数组cbuf 中,从 偏移量off 开始的 len个字符 数据,写入到该文件字符输出流 |
void | write(String str, int off, int len) | 将 字符串str 中,从 偏移量off 开始的 len个字符 数据,写入到该文件字符输出流 |
void | flush() | 刷新流,需要刷新流,数据才会真正写入到文件 |
void | close() | 内部调用刷新流方法,再关闭流,释放资源 |
package com.wei.java.basic.io;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class FileWriter_my {
public static void main(String[] args) throws IOException {
String filePath = "D:\\IdeaProjects\\my-study\\java-basic\\java-basic-begin\\src\\main\\resources\\io\\text_01.txt";
String outFilePath = "D:\\IdeaProjects\\my-study\\java-basic\\java-basic-begin\\src\\main\\resources\\io\\out_01.txt";
try (
FileReader fr = new FileReader(filePath);
){
FileWriter fw = new FileWriter(outFilePath);
fw.write("w");
char[] chars = new char[2];
int len;
while ((len = fr.read(chars)) != -1){
fw.write(chars, 0, len);
}
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
BufferedReader 带缓冲区的字符输入流
构造器 | 方法说明 |
---|
BufferedReader(Reader in) | 有参构造,传入 Reader 对象 |
返回类型 | 方法 | 方法说明 |
---|
int | read() | 从该带缓冲区的字符输入流中读取 下一个字节,并返回 该字节 对应的 整型数值 |
int | read(char[] cbuf) | 从该带缓冲区的字符输入流读取最多 cbuf.length 个字符的数据放入 字符数组cbuf,并返回读取到的字符个数 |
int | read(char[] cbuf, int offset, int length) | 从该带缓冲区的字符输入流读取最多 length 个字节的数据放入 字符数组cbuf,并返回读取到的字符个数 |
String | readLine() | 读取一行字符串,并返回该行字符串 |
void | close() | 关闭流并释放与之相关联的任何系统资源 |
package com.wei.java.basic.io;
import java.io.BufferedReader;
import java.io.FileReader;
public class BufferedReader_my {
public static void main(String[] args) throws Exception {
String filePath = "D:\\IdeaProjects\\my-study\\java-basic\\java-basic-begin\\src\\main\\resources\\io\\text_01.txt";
FileReader fr = new FileReader(filePath);
BufferedReader br = new BufferedReader(fr);
int charInt = br.read();
System.out.println((char) charInt);
String line = br.readLine();
System.out.println(line);
String src;
while ((src = br.readLine()) != null) {
System.out.println(src);
}
br.close();
}
}
BufferedWriter 带缓冲区的字符输出流
构造器 | 方法说明 |
---|
BufferedWriter(Writer out) | 有参构造,传入 Writer 对象 |
返回类型 | 方法 | 方法说明 |
---|
void | write(int c) | 写一个字符 |
void | write(char[] cbuf, int off, int len) | 将 字符数组cbuf 中,从 偏移量off 开始的 len个字符 数据,写入到该带缓冲区的字符输出流 |
void | write(String str, int off, int len) | 将 字符串str 中,从 偏移量off 开始的 len个字符 数据,写入到该带缓冲区的字符输出流 |
void | newLine() | 写入一换行符 |
void | flush() | 刷新流,需要刷新流,数据才会真正写入到文件 |
void | close() | 内部调用刷新流方法,再关闭流,释放资源 |
package com.wei.java.basic.io;
import java.io.*;
public class BufferedWriter_my {
public static void main(String[] args) throws Exception {
String filePath = "D:\\IdeaProjects\\my-study\\java-basic\\java-basic-begin\\src\\main\\resources\\io\\text_01.txt";
String outFilePath = "D:\\IdeaProjects\\my-study\\java-basic\\java-basic-begin\\src\\main\\resources\\io\\out_01.txt";
try (
FileReader fr = new FileReader(filePath);
BufferedReader bf = new BufferedReader(fr);
FileWriter fw = new FileWriter(outFilePath);
) {
BufferedWriter bw = new BufferedWriter(fw);
char[] chars = new char[2];
int len;
while ((len = bf.read(chars)) != -1) {
bw.write(chars, 0, len);
}
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
常用流的分类与选择
![在这里插入图片描述](https://img-blog.csdnimg.cn/5f3cd9f339e74d7a8857c76172f26bb8.png)
小结:
- 字符流只适用于操作纯文本文件
- 字节流可以操作任何文件