1.IO流的分类:
A:数据流向不同
输入流 读取数据
输出流 写入数据
B:操作数据类型不同
字节流
字符流 用记事本打开能读懂的就用字符流
2.字符流的体系结构:
Reader
|--FileReader
|--BufferedReader
Writer
|--FileWriter
|--BufferedWriter
InputStream
|--FileInputStream
|--一次读取一个字节
|--一次读取一个字节数组
|--BufferedInputStream 没有特殊方法
OutputStream
|--FileOutputStream
|--BufferedOutputStream 没有特殊方法
3.字符流输出流写入方法:
步骤:
A:创建字符输出流对象
B:调用对象的写入方法
write(int ch)
write(char[] chs,int index,int length)
write(String str)
C:释放资源
4.字符输入流读入方法:
步骤:
A:创建字符输入流对象
B:调用对象的读取方法
int read()
int read(char[] chs)
C:释放资源
5.复制文件
数据源:
a.txt -- 读取数据 -- Reader -- FileReader
目的地:
b.txt -- 写入数据 -- Writer -- FileWriter
复制文件第一种方式:一个字符一个字符的复制,每次的读写比较耗时,而且读取内存很消耗资源。
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class CopyFileDemo {
public static void main(String[] args) throws IOException {
//封装数据源输入流对象
FileReader fr = new FileReader("fw.txt");
//封装目的地输出流对象
FileWriter fw = new FileWriter("copy.txt");
int num=0;
//只要读取的整数不是-1就写入
while((num=fr.read())!=-1){
fw.write(num);
}
//关闭输入流和输出流
fr.close();
fw.close();
}
}
复制文件第二种方式:用字符数组来复制,读满一个字符数组之后再写入,这样更加节省时间。
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class CopyFileDemo1 {
public static void main(String[] args) throws IOException {
//封装数据源输入流对象
FileReader fr = new FileReader("fw.txt");
//封装目的地输出流对象
FileWriter fw = new FileWriter("copy1.txt");
//定义读入的字符串数组
char[] chs =new char[100];
int len=0;
//只要读取的字符串数组长度不为-1就写入目的地文件中
while((len=fr.read(chs))!=-1){
fw.write(chs, 0, len);
fw.flush();
}
//关闭输入和输出流
fr.close();
fw.close();
}
}
复制文件时的异常处理
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class CopyFileDemo1 {
public static void main(String[] args){
FileReader fr=null;
FileWriter fw=null;
char[] chs =new char[100];
int len=0;
try {
fr = new FileReader("fw.txt");
fw = new FileWriter("copy1.txt");
while((len=fr.read(chs))!=-1){
fw.write(chs, 0, len);
fw.flush();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}
try {
if(fr!=null)
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if(fw!=null)
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
6.字符高效流
它只是提供高效的读写,真正底层操作使用的还是传递过来的基本流对象
BufferedReader:
特殊方法 public String readLine()
BufferedWriter:
特殊方法 public void newLine()
使用高效流复制文本文件:
数据源:
a.txt -- 读取数据 -- Reader -- FileReader -- BufferedReader
目的地:
b.txt -- 写入数据 -- Writer -- FileWriter -- BufferedWriter
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class CopyFileDemo2 {
public static void main(String[] args) throws IOException {
//封装数据源字符高效输入流对象
BufferedReader br = new BufferedReader(new FileReader("fw.txt"));
//封装目的地字符高效输出流对象
BufferedWriter bw = new BufferedWriter(new FileWriter("copy2.txt"));
String line=null;
//只要读入的字符串不为空就写入目的地文件
while((line=br.readLine())!=null){
bw.write(line);
bw.newLine();
bw.flush();
}
//关闭输入输出流
br.close();
bw.close();
}
}
7.转换流
InputStreamReader:字节流通向字符流的桥梁
OutputStreamWriter:字符流通向字节流的桥梁
8.IO流复制文件操作规律
(1)文本文件 -- 文本文件
BufferedReader br = new BufferedReader(new FileReader("a.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt"));
String line = null;
while((line=br.readLine())!=null)
{
bw.write(line);
bw.newLine();
bw.flush();
}
bw.close();
br.close();
(2)文本文件 -- 控制台输出
BufferedReader br = new BufferedReader(new FileReader("a.txt"));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
String line = null;
while((line=br.readLine())!=null)
{
bw.write(line);
bw.newLine();
bw.flush();
}
bw.close();
br.close();
(3)键盘录入 -- 文本文件
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt"));
String line = null;
while((line=br.readLine())!=null)
{
if("over".equals(line))
{
break;
}
bw.write(line);
bw.newLine();
bw.flush();
}
bw.close();
br.close();
(4)键盘录入 -- 控制台输出
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
String line = null;
while((line=br.readLine())!=null)
{
//如果数据源是键盘录入,就得自定义结束
if("over".equals(line)
{
break;
}
bw.write(line);
bw.newLine();
bw.flush();
}
bw.close();
br.close();
/*
* 需求:将e:\\java目录下所有的java文件复制到e:\\jad目录下,并将文件名改为以.jad结尾
*
*/
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.FilenameFilter;
import java.io.IOException;
public class CopyFolder {
public static void copyFiles(File src)throws IOException{
File[] fileArray=src.listFiles();
//封装目标地输出流对象
File target = new File("e:\\jad");
//如果目标文件不存在,创建目标文件
if(!target.exists()){
target.mkdir();
}
if(fileArray!=null){
//遍历文件夹中的文件,如果是文件夹就采用递归函数继续寻找,否则就改变名字
for(File file : fileArray){
if(file.isDirectory()){
copyFiles(file);
}
else{
if(file.getName().endsWith(".java")){
String oldName = file.getName();
String newName = oldName.replace(".java", ".jad");
File newFile = new File(target,newName);
BufferedReader br = new BufferedReader(new FileReader(file));
BufferedWriter bw = new BufferedWriter(new FileWriter(newFile));
String line = null;
while((line=br.readLine())!=null){
bw.write(line);
bw.newLine();
bw.flush();
}
bw.close();
br.close();
}
}
}
}
}
public static void main(String[] args)throws IOException {
//封装数据源(d:\\java)
File src=new File("e:\\java");
//判断文件夹是否存在(若不存在就提示源文件夹不存在)
if(!(src.exists())){
throw new RuntimeException("源文件夹不存在");
}
//调用复制文件的函数
copyFiles(src);
}
}
学习感悟:IO流中最重要还是掌握高效字节流输入和输出的用法,字节和数组的读入和写入是为了帮助我们更好的理解字节流和字符流的操作原理。FileWriter其实底层还是用OutputStream实现的,只不过它同时封装了输出流和编码,所以我们直接使用会更加方便。