IO流_复制文件夹
复制单级文件夹
什么是单级文件夹:该文件夹里面只有小文件,没有小文件夹 什么是多级文件夹:该文件夹里面有小文件,也有小文件夹
复制文件夹的时候,会把该文件夹里面的小文件也复制
需求:把"D:\huanf\java\src\ch18_ch19储物区\JavaZM"文件夹复制到"D:\huanf\java\src\ch18_ch19储物区\JavaWEB"文件夹里面
思路: 1、创建数据源目录File对象,路径是"D:\huanf\java\src\ch18_ch19_储物区\JavaZM" 2、获取数据源目录File对象的名称,即JavaWEB 3、创建目的地目录File对象,路径名是模块名+JavaWEB 4、判断目的地目录对应的File是否存在,如果不存在,就创建 5、获取数据源目录下的所有文件的File数组 6、遍历File数组,得到每一个File对象,该File对象,其实就是数据源文件 (1)比如原JavaZM目录下可能还会有小文件,例如JavaZM\Text.txt 7、获取数据源文件File对象的名称 (1)例如Text.txt 8、创建目的地文件File对象,路径名是目的地目录+Text.txt 9、复制文件 (1)由于文件不仅仅是文本文件,还有图片、视频等文件,所以采用字节流复制文件
复制单级文件夹的练习
xxxxxxxxxx
package ch20;
import java.io.*;
//把JavaZM包括里面的子文件,复制到JavaWEB里面,建议去文件管理器查看,idea看的不直观
public class a_2_1测试 {
public static void main(String[] args) throws IOException {
//1、创建数据源目录File对象,路径是"D:\huanf\java\src\ch18_ch19_储物区\JavaZM"
File srcFolder = new File("D:\\huanf\\java\\src\\ch18_ch19_储物区\\JavaZM");
//2、获取数据源目录File对象的名称,即JavaWEB
String srcFolderName = srcFolder.getName();
//3、创建目的地目录File对象,路径名是模块名+JavaWEB
File destFolder = new File("D:\\huanf\\java\\src\\ch18_ch19_储物区\\JavaWEB",srcFolderName);
//4、判断目的地目录对应的File是否存在,如果不存在,就创建
if(!destFolder.exists()){
destFolder.mkdir();
}
//5、获取数据源目录下的所有文件的File数组
File[] listFiles = srcFolder.listFiles();
//6、使用增强for来遍历File数组,得到每一个File对象,该File对象,其实就是数据源文件
for(File srcFile : listFiles){
//(1)比如原JavaZM目录下可能还会有小文件,例如JavaZM\Text.txt
//7、获取数据源文件File对象的名称
String srcFileName = srcFile.getName();
//8、创建目的地文件File对象,路径名是目的地目录+Text.txt
File destFile = new File(destFolder,srcFileName);
//9、复制文件。在外面写一个copyFile复制文件方法,再下面那行调用
copyFile(srcFile,destFile);//选中copyFile,按Alt+Enter,选Create method... ,自动生成方法
}
}
//自动生成的方法
private static void copyFile(File srcFile, File destFile) throws IOException {
//报红线就选中它,按Alt+Enter,抛出异常
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFile));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile));
//读数据
byte[] bys = new byte[1024];
int len;
while ((len=bis.read(bys))!=-1){
bos.write(bys,0,len);
}
//释放资源
bos.close();
bis.close();
}
}
复制多级文件夹
什么是单级文件夹:该文件夹里面只有小文件,没有小文件夹 什么是多级文件夹:该文件夹里面有小文件,也有小文件夹
复制文件夹的时候,会把该文件夹里面的小文件和小文件夹也复制
需求:把"D:\huanf\java\src\ch18_ch19储物区\JavaWEB"文件夹复制到"D:\huanf\java\src\ch18_ch19储物区\JavaBM"文件夹里面 注意:JavaWEB是多级文件夹,我们要把JavaWEB文件夹复制到JavaBM文件夹里面
思路: 1、创建数据源File对象,路径是"D:\huanf\java\src\ch18_ch19储物区\JavaWEB" 2、创建目的地File对象,路径是"D:\huanf\java\src\ch18_ch19储物区\JavaBM" 3、写方法实现文件夹的复制,参数为数据源File对象和目的地File对象。这个方法是复制文件夹的 4、在复制文件夹的方法的内部判断数据源File是否是目录 (1)是: 11、先在目的地下创建和数据源File名称一样的目录 22、再获取数据源FIle下所有文件或者目录的File数组 33、再使用增强for来遍历该FIle数组,得到每一个File对象,这个File对象可能是文件对象,也可能是目录对象 44、把该File作为数据源File对象,递归调用复制文件夹的方法。如果是目录就再从这里的"是"的11~44来一遍 (2)不是: 111、说明是文件直接复制,用字节流
复制多级文件夹的练习
xxxxxxxxxx
package ch20;
import java.io.*;
public class a_3_1测试 {
public static void main(String[] args) throws IOException {
//1、创建数据源File对象,路径是"D:\huanf\java\src\ch18_ch19_储物区\JavaWEB"
File srcFile = new File("D:\\huanf\\java\\src\\ch18_ch19_储物区\\JavaWEB");
//2、创建目的地File对象,路径是"D:\huanf\java\src\ch18_ch19_储物区\JavaBM"
File destFile = new File("D:\\huanf\\java\\src\\ch18_ch19_储物区\\JavaBM");
//3、写方法实现文件夹的复制,参数为数据源File对象和目的地File对象。快捷生成对应copyFolder方法,按Alt+Enter,选Create method...
copyFolder(srcFile, destFile);//格式copyFolder(数据源,目的地)。报红线就抛出异常
}
//快捷生成的对应方法、这个方法是复制文件夹的
private static void copyFolder(File srcFile, File destFile) throws IOException {
//4、在复制文件夹的方法的内部判断数据源File是否是目录
if (srcFile.isDirectory()) {//如果是目录
//11、先在目的地下创建和数据源File名称一样的目录
String srcFileName = srcFile.getName();
File newFolder = new File(destFile, srcFileName);//封装了目的地destFile路径对应的数据源srcFile,即封装成一个新目录
if (!newFolder.exists()) {//如果新目录不存在就创建
newFolder.mkdir();//注意别写成mkdirs
}
//22、再获取数据源FIle下所有文件或者目录的File数组
File[] fileArray = srcFile.listFiles();
//33、再使用增强for来遍历该FIle数组,得到每一个File对象,这个File对象可能是文件对象,也可能是目录对象
for(File file : fileArray){
//44、把该File作为数据源File对象,递归调用复制文件夹的方法。如果是目录就再从这里的"是"的11~44来一遍
copyFolder(file,newFolder);//格式copyFolder(数据源,目的地)
}
} else{//如果是文件
//111、说明是文件直接复制,用字节流
//下面那行先封装一下目的地文件,后面会用到
File newFile = new File(destFile,srcFile.getName());//srcFile.getName()的作用是得到数据源文件的名称
copyFile(srcFile,newFile);//报红线就抛出异常
}
}
//字节缓冲流复制文件的方法,注意下面这个方法是复制文件的,不是复制文件夹
private static void copyFile(File srcFile, File destFile) throws IOException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFile));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile));
byte[] bys = new byte[1024];
int len;
while ((len = bis.read(bys)) != -1) {
bos.write(bys, 0, len);
}
bos.close();
bis.close();
}
}
复制文件的异常处理
【第一种解决异常的写法】throws IOException 抛出异常
【第二种解决异常的写法】try...catch...finally
try{
可能出现异常的代码;
}catch(异常类名 变量名){
异常的处理代码;
}finally{
执行所有清除操作;
}
【第三种解决异常的写法】try...catch 。即JDK7之后的改进方案。特点是自动释放资源
x
try(定义流对象){
可能出现异常的代码;
}catch(异常类名 变量名){
异常的处理代码;
}
【第四种解决异常的写法】先定义,再try...catch 。即JDK9之后的改进方案。特点是自动释放资源
x
定义输入流对象;
定义输出流对象;
try(输入流对象;输出流对象){
可能出现异常的代码;
}catch(异常类名 变量名){
异常的处理代码;
}
复制文件异常处理的练习
xxxxxxxxxx
package ch20;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class a_4_1测试 {
public static void main(String[] args) {
}
//该方法的作用是复制文本文件。这不重要。我们主要是看报红线的异常
//之前抛出异常是在下面那行加throws IOException,这样的做法是抛出处理,并不是真正的处理。如何不抛出,直接在方法内部把异常处理掉
//即第一种处理写法,如下,弊端是没有真正解决只是抛出异常
//注意这部分代码是没有改动的,后面的第二种、第三种写法的代码都是复制这部分的,然后做出改变
private static void method1() throws IOException {
FileReader fr = new FileReader("");
FileWriter fw = new FileWriter("");
char[] chs = new char[1024];
int len;
while ((len = fr.read())!=-1){
fw.write(chs,0,len);
}
fw.close();
fr.close();
}
//----------------------------------------------------------------------------------------------------------------
//我们想要真正处理异常,就使用try...catch...finally
//即第二种处理异常写法,如下,弊端是代码复杂了一些
private static void method2() {
//注意定义写在外面,并且要进行初始化,即赋值为null
FileReader fr = null;
FileWriter fw = null;
try { //try里面就是我们可能出现异常的代码
/*FileReader fr = new FileReader("");
FileWriter fw = new FileWriter("");*/ //这里的定义我们要写在外面,不然下面finally里面的fw和fr会由于作用域的问题报红线。如下
fr = new FileReader("");
fw = new FileWriter("");
char[] chs = new char[1024];
int len;
while ((len = fr.read()) != -1) {
fw.write(chs, 0, len);
}
}catch (IOException e){
e.printStackTrace();
}finally {//释放资源的操作要写在finally里面
if(fw!=null) { //不等于null,才需要调用close
try {
fw.close();//这里的close还会报红线,则选中,Alt+Enter,选Surround with try/catch
} catch (IOException e) {
e.printStackTrace();
}
}
//下面同理
if(fr!=null) {
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//------------------------------------------------------------------------------------------------------------------
//第三种处理异常写法。JDK7之后的改进方案。非常好用,唯一的不足就是try()里面的代码量多
private static void method3() {
try(FileReader fr = new FileReader("");
FileWriter fw = new FileWriter("")){
char[] chs = new char[1024];
int len;
while ((len = fr.read())!=-1){
fw.write(chs,0,len);
}
}catch(IOException e){
e.printStackTrace();
}
}
//-------------------------------------------------------------------------------------------------------------------
//第四种处理异常写法。JDK9之后的改进方案。非常好用,唯一的不足就是由于把定义放在了try外面,所以定义部分的代码还是需要抛出异常
private static void method4() throws IOException{
FileReader fr = new FileReader("");
FileWriter fw = new FileWriter("");
try(fr;fw){
char[] chs = new char[1024];
int len;
while ((len = fr.read())!=-1){
fw.write(chs,0,len);
}
}catch(IOException e){
e.printStackTrace();
}
}
//-------------------------------------------------------------------------------------------------------------------
//总结:
//1、JDK7那种写法是没有使用到抛出异常的,即真正解决了异常,唯一的不足就是try()小括号里面的代码乱了一点点。但是确实非常非常好用
//2、JDK9那种写法优化了JDK那种写法的小括号问题。唯一的不足就是在定义那里没有真正解决异常,而是使用抛出异常
}