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)由于文件不仅仅是文本文件,还有图片、视频等文件,所以采用字节流复制文件
复制单级文件夹的练习
xxxxxxxxxxpackage 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、说明是文件直接复制,用字节流
复制多级文件夹的练习
xxxxxxxxxxpackage 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(异常类名 变量名){ 异常的处理代码;}
复制文件异常处理的练习
xxxxxxxxxxpackage 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那种写法的小括号问题。唯一的不足就是在定义那里没有真正解决异常,而是使用抛出异常
}