IO流的分类
- 根据流的流向分类:
-
- 输入流:将数据从
其他设备
上读取到内存
中的流。以 InputStream 、Reader 结尾。 - 输出流:将数据从
内存
中写出到其他设备
上的流。以 OutputStream 和 Writer 结尾。
- 输入流:将数据从
- 根据数据的类型分类:
-
- 字节流:以字节为单位,读写数据的流。以 InputStream 和 OutputStream 结尾。
- 字符流:以字符为单位,读写数据的流。以 Reader 和 Writer 结尾。
- 根据 IO 流的角色不同分类:
-
- 节点流:可以从或向一个特定的地方(节点)读取数据。如 FileReader 。
- 处理流:对一个已经存在的流进行连接和封装,通过锁封装的流的功能实现数据读写。如:BufferReader ,处理流的构造方法总是要带一个其它的流对象做参数。一个流对象经过多次其它流的多次包装,称为流的链接。
- 常用的节点流:
-
- 文件:FileInputStream 、FileOutputStream 、FileReader 、FileWriter 文件进行处理的节点流。
- 字符串:StringReader 、StringWriter 对字符串进行处理的节点流。
- 数组: ByteArrayInputStream 、ByteArrayOutputStream、CharArrayReader 、CharArrayWriter 对数组进行处理的节点流(对应的不再是文件,而是内存中的一个数组)。
- 管道:PipedInputStream 、PipedOutputStream 、PipedReader 、PipedWriter 对管道进行处理的节点流。
- 常用处理流:
-
- 缓冲流:BufferedInputStream 、BufferedOutputStream 、BufferedReader 、BufferedWriter ---增加缓冲功能,避免频繁读写硬盘。
- 转换流:InputStreamReader 、OutputStreamReader --- 实现字节流和字符流之间的转换。
- 数据流:DataInputStream 、DataOutputStream - 提供读写 Java 基础数据类型功能。
- 对象流:ObjectInputStream 、ObjectOutputStream -- 提供直接读写 Java 对象功能。
输入流 |
输出流 | |
字节流 |
字节输入流 InputStream |
字节输出流 OutputStream |
字符流 |
字符输入流 Reader |
字符输出流 Writer |
字符流
- 如果利用字节流,把文本文件的中文,读取到内存中,有可能还会出现乱码
- 如果利用字节流,把中文写到文本文件中,也有可能出现乱码
字符流概述
由于字节流操作中文不是特别的方便,所以Java就提供字符流
字符流 = 字节流 + 编码表
代码演示:
import java.io.FileReader;
import java.io.FileWriter;
/*
* flush()刷新和close()关闭方法的差别
* close()方法中包含flush()方法
*
* FileOutputStream(字节流)
* 字节流也是有缓冲区的,不过很小,可以忽略不计
* FileWriter(字符流)
* 该类的构造函数假定默认字符编码和默认字节缓冲区大小是可以接受的
*
* 在使用字符流写数据的时候,并不是直接写到文件中的,而是先保存到缓冲区,如果需要再写入到文件中(需要手动的刷新流和关闭流对象)
*
* */
public class FileWrite {
public static void main(String[] args) throws Exception {
//写数据
FileWriter fw = new FileWriter("aaa.txt");
String str = "恭喜发财";
fw.write(str);
fw.close();
//读数据
FileReader fr = new FileReader("aaa.txt");
//由于此处read为int类型,所以转换是ASCLL码;(可以用char转换为字符)
int read;
/*while ((read=fr.read())!=-1){
System.out.println("read = " + (char)read);
}*/
//也可以使用char[]数组进行存储后输出
char[] chars = new char[1024];
while ((read=fr.read(chars))!=-1){
System.out.println(new String(chars,0,read));
}
fr.close();
}
}
字节缓冲流
2.6.1 缓冲流概述
- 缓冲流,也叫高效流,按照数据类型分类:
-
- 字节缓冲流:BufferedOutputStream 、BufferedInputStream 。
- 字符缓冲流:BufferedReader 、BufferedWriter 。
- 缓冲流会在内部创建一个缓冲区数组,缺省使用 8192 个字节(8kb)的缓冲区。
- 缓冲流仅仅提供缓冲区,而真正的读写数据还得依靠基本的字节流、字符流对象进行操作
由于字符与字节差不多,所以这里只写一个字节的缓冲流了
字节缓冲流
字节缓冲流介绍
- lBufferOutputStream:该类实现缓冲输出流.通过设置这样的输出流,应用程序可以向底层输出流写入字节,而不必为写入的每个字节导致底层系统的调用
- lBufferedInputStream:创建BufferedInputStream将创建一个内部缓冲区数组.当从流中读取或跳过字节时,内部缓冲区将根据需要从所包含的输入流中重新填充,一次很多字节
构造方法:
方法名 |
说明 |
BufferedOutputStream(OutputStream out) |
创建字节缓冲输出流对象 |
BufferedInputStream(InputStream in) |
创建字节缓冲输入流对象 |
代码演示:
import java.io.*;
public class Buffered {
public static void main(String[] args) throws Exception {
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("aaa.txt"));
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("aaa.txt"));
//写数据
String str = "红包拿来";
bos.write(str.getBytes());
//释放资源
bos.close();
//读数据
int read;
byte[] bytes = new byte[1024];
while ((read=bis.read(bytes))!=-1){
System.out.println(new String(bytes,0,read));
}
//释放资源
bis.close();
}
}
字节缓冲流复制文件
- 案例需求
把“aaa.txt”复制到模块目录下的“abc.txt” - 实现步骤
-
- 根据数据源创建字节输入流对象
- 根据目的地创建字节输出流对象
- 读写文本,复制数据
- 释放资源
这里我写了三种效率不同的方法,可以自己手动运行看下差别
代码演示:
import java.io.*;
public class BuffereInputStream {
public static void main(String[] args) throws Exception {
//user();
//vip_user();
//Svip_user();
}
public static void user() throws Exception {
long start = System.currentTimeMillis();
FileInputStream fis = new FileInputStream("aaa.txt");
FileOutputStream fos = new FileOutputStream("abc.txt");
int read;
while ((read=fis.read())!=-1){
fos.write(read);
}
long end = System.currentTimeMillis();
System.out.println(" 耗时: " + (end - start));
//释放资源
fos.close();
fis.close();
}
public static void vip_user() throws Exception {
long start = System.currentTimeMillis();
FileInputStream fis = new FileInputStream("aaa.txt");
FileOutputStream fos = new FileOutputStream("abc.txt");
int read;
byte[] bytes = new byte[1024];
while ((read=fis.read(bytes))!=-1){
fos.write(bytes,0,read);
}
long end = System.currentTimeMillis();
System.out.println(" 耗时: " + (end - start));
//释放资源
fos.close();
fis.close();
}
public static void Svip_user() throws Exception {
long start = System.currentTimeMillis();
FileInputStream fis = new FileInputStream("aaa.txt");
BufferedInputStream bis = new BufferedInputStream(fis);
FileOutputStream fos = new FileOutputStream("abc.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos);
int read;
byte[] bytes = new byte[1024];
while ((read=bis.read(bytes))!=-1){
bos.write(bytes,0,read);
}
long end = System.currentTimeMillis();
//释放资源
bos.close();
fos.close();
bis.close();
fis.close();
System.out.println(" 耗时: " + (end - start));
}
}