文章目录
流的概念
按流的方向分类:
1. 输入流:数据流向是数据源到程序(以InputStream、Reader结尾的流)。
2. 输出流:数据流向是程序到目的地(以OutPutStream、Writer结尾的流)。
按处理的数据单元分类:
- 字节流:以字节为单位获取数据,命名上以
Stream
结尾的流一般是字节流,如FileInputStream、FileOutputStream
。 - 字符流:以字符为单位获取数据,命名上以
Reader/Writer
结尾的流一般是字符流,如FileReader、FileWriter
。
按处理对象不同分类:
- 节点流:可以直接从数据源或目的地读写数据,如
FileInputStream、FileReader、DataInputStream
等。 - 处理流:不直接连接到数据源或目的地,是”处理流的流”。通过对其他流的处理提高程序的性能,如
BufferedInputStream、BufferedReader
等。处理流也叫包装流。
IO 流类体系
InputStream / OutputStream
表示字节输入输出流的所有类的父类。
子类:
FileInputStream / FileOutputStream
: 节点流,以字节为单位 【直接】操作『文件』ByteArrayInputStream / ByteArrayOutputStream
:节点流,…操作『字节数组对象』ObjectInputStream / ObjectOutputStream
:处理流,…『对象』DataInputStream / DataOutputStream
:处理流,…『基本数据类型与字符串类型』
Reader / Writer
表示用于读取/写入的字符流抽象类,数据单位为字符.
子类:
FileReader / FileWriter
:节点流,以字符为单位直接操作『文本文件』(只能读写文本文件)BufferedReader / BufferedWriter
:处理流,将Reader/Writer对象进行包装,增加缓存功能,提升读写效率BufferedInputStream / BufferedOutputStream
:处理流,将InputStream/OutputStream对象包装,…InputStreamReader / OutputStreamWriter
:处理流,将字节流对象转化为字符流对象PrintStream
:处理流,将OutputStream进行包装,可以方便地输出字符
文件字节流
fis = new FileInputStream("a.txt");
while ((tmp = fis.read()) != -1)
sb.append((char) tmp);
...
FileOutputStream fos = null;
String string = "i am writing.";
try {
fos = new FileOutputStream("a.txt", true); // true表示追加文件末尾
byte[] bytes = string.getBytes();
fos.write(bytes); // 直接将字符数组写入文件
文件字符流
字节流不能很好的处理Unicode字符,经常会出现“乱码”现象,一般使用字符流处理文本文件。
FileReader fr = null;
FileWriter fw = null;
try {
fr = new FileReader("a.txt");
fw = new FileWriter("./c.txt");
char[] buffer = new char[1024]; // 缓存数组
int len = 0;
while ((len = fr.read(buffer)) != -1)
fw.write(buffer, 0, len);
} catch (Exception e) {...
缓冲字节流
Java缓冲流本身并不具有IO流的读取与写入功能,只是在别的流(节点流或其他处理流)上加上缓冲功能提高效率,就像是把别的流包装起来一样,因此缓冲流是一种处理流(包装流)。
因为缓冲流是先将数据缓存起来,然后当缓存区存满后或者手动刷新时再一次性的读取到程序或写入目的地。
// 使用缓冲流实现文件的高效率复制
FileInputStream fis = null;
BufferedInputStream bis = null;
FileOutputStream fos = null;
BufferedOutputStream bos = null;
String srcPath = "/home/cenjw/Downloads/ideaIU-2019.3.5.tar.gz";
String destPath = "/home/cenjw/idea-package.tar.gz";
try {
fis = new FileInputStream(srcPath);
fos = new FileOutputStream(destPath);
bis = new BufferedInputStream(fis);
bos = new BufferedOutputStream(fos);
int t = 0;
long start = System.currentTimeMillis();
while ((t = bis.read()) != -1)
bos.write(t);
long end = System.currentTimeMillis();
System.out.println(end - start);
缓冲字符流
FileReader fr = null;
BufferedReader br = null;
FileWriter fw = null;
BufferedWriter bw = null;
try {
fr = new FileReader("a.txt");
fw = new FileWriter("./d.txt");
br = new BufferedReader(fr);
bw = new BufferedWriter(fw);
String tmpStr = "";
while ((tmpStr = br.readLine()) != null) {
bw.write(tmpStr);
bw.newLine();
}
-
readLine()方法是BufferedReader特有的方法,可以对文本文件进行更加方便的读取操作。
-
写入一行后要记得使用newLine()方法换行。
字节数组流
ByteArrayInputStream和ByteArrayOutputStream经常用在需要流和数组之间转化的情况!
即,FileInputStream是把文件当做数据源。ByteArrayInputStream则是把内存中的”某个字节数组对象”当做数据源。
// 字符串转变为字节数组
byte[] bytes = "hello world".getBytes();
ByteArrayInputStream bais = null;
StringBuilder sb = new StringBuilder();
try {
int tmp = 0;
int cnt = 0;
bais = new ByteArrayInputStream(bytes);
while ((tmp = bais.read()) != -1) {
sb.append((char) tmp);
cnt++;
}