IO流的概念
- IO就是Input和Output的简写,也就是输入和输出的含义。
- IO流就是指读写数据时像流水一样从一端流到另外一端,因此得名为“流"。
基本的分类
- 按照处理数据的基本单位不同,分为字节流和字符流。
其中字节流主要指以字节为单位进行数据读写的流,可以读写任意类型的文件。
其中字符流主要指以字符(2个字节)为单位进行数据读写的流,只能读写文本文件。 - 按照读写数据的方向不同,分为输入流和输出流
其中输入流主要指从文件中读取数据内容输入到程序中,也就是读文件。
其中输出流主要指将程序中的数据内容输出到文件中,也就是写文件。 - 按照流的角色不同分为节点流和处理流。
其中节点流主要指直接和输入输出源对接的流。
其中处理流主要指需要建立在节点流的基础之上的流。
体系结构

重要的IO流类:

1.1FileWriter类
- java.io.FileWriter类主要用于将文本内容写入到文本文件。
| 方法声明 | 功能介绍 |
|---|
| FileWriter(String fileName) | 根据参数指定的文件名构造对象 |
| FileWriter(String fileName, booleanappend) | 以追加的方式根据参数指定的文件名来构造对象,即不清空原文件内容再写入 |
| void write(int c) | 写入单个字符 |
| void write(char[] cbuf, int off, int len) | 将指定字符数组中从偏移量off开始的len个字符写入此文件输出流 |
| void write(char[] cbuf) | 将cbuf.length个字符从指定字符数组写入此文件输出流中 |
| void flush() | 刷新流 |
| void close() | 关闭流对象并释放有关的资源 |
使用举例:
public static void main(String[] args) {
FileWriter fw= null;
try {
fw = new FileWriter("d:/a.txt");
fw.write('s');
char[] cArr={'h','e','l','l','o'};
fw.write(cArr,2,2);
fw.write(cArr);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(null!=fw)
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
1.2FileReader类
- java.io.FileReader类主要用于从文本文件读取文本数据内容。
常用的方法
| 方法声明 | 功能介绍 |
|---|
| FileReader(String fileName) | 根据参数指定的文件名构造对象 |
| int read() | 读取单个字符的数据并返回,返回-1表示读取到末尾 |
| int read(char[] cbuf, int offset, int length) | 从输入流中将最多len个字符的数据读入一个字符数组中,返回读取到的字符个数,返回-1表示读取到末尾 |
| int read(char[] cbuf) | 从此输入流中将最多 cbuf.length 个字符的数据读入字符数组中,返回读取到的字符个数,返回-1表示读取到末尾 |
| void close() | 关闭流对象并释放有关的资源 |
使用举例:
public static void main(String[] args) {
FileReader fr= null;
try {
fr = new FileReader("d:/a.txt");
int res=fr.read();
System.out.println("获取到的字符是:"+(char)res);
StringBuilder sb=new StringBuilder();
while((res=fr.read())!=-1){
sb.append((char)res);
}
System.out.println(sb);
} catch (IOException e) {
e.printStackTrace();
} finally {
if(null!=fr) {
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2.1FileOutputStream类
- java.io.FileOutputStream类主要用于将图像数据之类的原始字节流写入到输出流中。
- 相较于FileWriter只能写入文本文件,FileOutputStream可以写入任意文件如图像、视频等。
| 方法声明 | 功能介绍 |
|---|
| FileOutputStream(String name) | 根据参数指定的文件名来构造对象 |
| FileOutputStream(String name, boolean append) | 以追加的方式根据参数指定的文件名来构造对象 |
| void write(int b) | 将指定字节写入此文件输出流 |
| void write(byte[] b, int off, int len) | 将指定字节数组中从偏移量off开始的len个字节写入此文件输出流 |
| void write(byte[] b) | 将 b.length 个字节从指定字节数组写入此文件输出流中 |
| void flush() | 刷新此输出流并强制写出任何缓冲的输出字节 |
| void close() | 关闭流对象并释放有关的资源 |
2.2FileInputStream类
- java.io.FileInputStream类主要用于从输入流中以字节流的方式读取图像数据等。
常用方法为:
| 方法声明 | 功能介绍 |
|---|
| FileInputStream(String name) | 根据参数指定的文件路径名来构造对象 |
| int read() | 从输入流中读取单个字节的数据并返回,返回-1表示读取到末尾 |
| int read(byte[] b, intoff, int len) | 从此输入流中将最多len个字节的数据读入字节数组中,返回读取到的字节个数,返回-1表示读取到末尾 |
| int read(byte[] b) | 从此输入流中将最多 b.length 个字节的数据读入字节数组中,返回读取到的字节个数,返回-1表示读取到末尾 |
| void close() | 关闭流对象并释放有关的资源 |
| int available() | 获取输入流所关联文件的大小 |
2.3使用举例:使用FileInputStream和FileOutputStream实现文件的拷贝。
方式一:以单个字节为单位拷贝,也就是每读取一个字节后再写入一个字节,该方法的缺点是当文件较大时,拷贝效率低。
public class ByteCopyTest {
public static void main(String[] args) {
FileInputStream fis= null;
FileOutputStream fos= null;
try {
fis = new FileInputStream("d:/测试图片.png");
fos = new FileOutputStream("d:/拷贝图片.png");
System.out.println("正在玩命加载中...");
int res;
while((res=fis.read())!=-1){
fos.write(res);
}
System.out.println("复制成功!");
} catch (IOException e) {
e.printStackTrace();
} finally {
if(null!=fis) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(null!=fos) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
方式二:准备一个和文件大小一样的缓冲区,一次性将所有文件内容读取到缓冲区再一次性写入。该方法的缺点是:当文件过大时,无法申请和文件一样大小的缓冲区,真实物理内存不足。
public class ByteCopyTest {
public static void main(String[] args) {
FileInputStream fis= null;
FileOutputStream fos= null;
try {
fis = new FileInputStream("d:/测试图片.png");
fos = new FileOutputStream("d:/拷贝图片.png");
System.out.println("正在玩命加载中...");
int volume=fis.available();
byte[] arr=new byte[volume];
System.out.println("正在玩命加载中...");
fis.read(arr);
fos.write(arr);
System.out.println("复制成功!");
} catch (IOException e) {
e.printStackTrace();
} finally {
if(null!=fis) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(null!=fos) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
方式三:选择一个相对适当的缓冲区,分多次将文件拷贝完成。
public class ByteCopyTest {
public static void main(String[] args) {
FileInputStream fis= null;
FileOutputStream fos= null;
try {
fis = new FileInputStream("d:/测试图片.png");
fos = new FileOutputStream("d:/拷贝图片.png");
System.out.println("正在玩命加载中...");
byte[] arr=new byte[1024];
System.out.println("正在玩命拷贝中...");
int res;
while((res=fis.read(arr))!=-1){
fos.write(arr,0,res);
}
System.out.println("拷贝成功!");
} catch (IOException e) {
e.printStackTrace();
} finally {
if(null!=fis) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(null!=fos) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
3.1BufferedOutputStream类
- java.io.BufferedOutputStream类主要用于描述缓冲输出流,此时不用为写入的每个字节调用底层
系统。该类相当于不再需要我们自己设置缓冲区,在内部自动进行缓冲操作。
| 方法声明 | 功能介绍 |
|---|
| BufferedOutputStream(OutputStream out) | 根据参数指定的引用来构造对象 |
| BufferedOutputStream(OutputStream out, intsize) | 根据参数指定的引用和缓冲区大小来构造对象 |
| void write(int b) | 写入单个字节 |
| void write(byte[] b, int off, int len) | 写入字节数组中的一部分数据 |
| void write(byte[] b) | 写入参数指定的整个字节数组 |
| void flush() | 刷新流 |
| void close() | 关闭流对象并释放有关的资源 |
3.2BufferedInputStream类
- java.io.BufferedInputStream类主要用于描述缓冲输入流。
| 方法声明 | 功能介绍 |
|---|
| BufferedInputStream(InputStream in) | 根据参数指定的引用构造对象 |
| BufferedInputStream(InputStream in, int size) | 根据参数指定的引用和缓冲区大小构造对象 |
| int read() | 读取单个字节 |
| int read(byte[] b) | 读取b.length个字节 |
| void close() | 关闭流对象并释放有关的资源 |
3.3使用缓冲字节流对象实现拷贝
public class BufferedByteCopyTest {
public static void main(String[] args) {
BufferedInputStream bis= null;
BufferedOutputStream bos= null;
try {
bis = new BufferedInputStream(new FileInputStream("d:/测试图片.png"));
bos = new BufferedOutputStream(new FileOutputStream("d:/拷贝图片.png"));
byte[] arr=new byte[1024];
System.out.println("正在玩命加载中...");
int res;
while((res=bis.read(arr))!=-1){
bos.write(arr,0,res);
}
System.out.println("拷贝成功!");
} catch (IOException e) {
e.printStackTrace();
} finally {
if(null!=bos) {
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(null!=bis) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
4.1BufferedWriter类
| 方法声明 | 功能介绍 |
|---|
| BufferedWriter(Writer out) | 根据参数指定的引用来构造对象 |
| BufferedWriter(Writer out, int sz) | 根据参数指定的引用和缓冲区大小来构造对象 |
| void write(int c) | 写入单个字符到输出流中 |
| void write(char[] cbuf, int off, int len) | 将字符数组cbuf中从下标off开始的len个字符写入输出流中 |
| void write(char[] cbuf) | 将字符串数组cbuf中所有内容写入输出流中 |
| void write(String s, int off, int len) | 将参数s中下标从off开始的len个字符写入输出流中 |
| void write(String str) | 将参数指定的字符串内容写入输出流中 |
| void newLine() | 用于写入行分隔符到输出流中 |
| void flush() | 刷新流 |
| void close() | 关闭流对象并释放有关的资源 |
4.2BufferedReader类
| 方法声明 | 功能介绍 |
|---|
| BufferedReader(Reader in) | 根据参数指定的引用来构造对象 |
| BufferedReader(Reader in, int sz) | 根据参数指定的引用和缓冲区大小来构造对象 |
| int read() | 从输入流读取单个字符,读取到末尾则返回-1,否则返回实际读取到的字符内容 |
| int read(char[] cbuf, int off, int len) | 从输入流中读取len个字符放入数组cbuf中下标从off开始的位置上,若读取到末尾则返回-1,否则返回实际读取到的字符个数 |
| int read(char[] cbuf) | 从输入流中读满整个数组cbuf |
| String readLine() | 读取一行字符串并返回,返回null表示读取到末尾 |
| void close() | 关闭流对象并释放有关的资源 |
4.3使用缓冲字符流对象实现文件拷贝
public class BufferedCharCopyTest {
public static void main(String[] args) {
BufferedReader br= null;
BufferedWriter bw= null;
try {
br = new BufferedReader(new FileReader("d:a.txt"));
bw = new BufferedWriter(new FileWriter("d:b.txt"));
String str="";
System.out.println("玩命加载中...");
while((str=br.readLine())!=null){
bw.write(str);
bw.newLine();
}
System.out.println("拷贝成功!");
} catch (IOException e) {
e.printStackTrace();
} finally {
}
if(null!=bw) {
try {
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(null!=br) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}