文件递归及异常


我们要想实现IO的操作,就必须知道硬盘上文件的表现形式。而Java就提供了一个类File供我们使用。
File:文件和目录(文件夹)路径名的抽象表示形式
构造方法:
  File(String pathname):根据一个路径得到File对象
  File(String parent, String child):根据一个目录和一个子文件/目录得到File对象
  File(File parent, String child):根据一个父File对象和一个子文件/目录得到File对象
创建方法:
public boolean createNewFile():创建文件 如果存在这样的文件,就不创建了
public boolean mkdir():创建文件夹 如果存在这样的文件夹,就不创建了
public boolean mkdirs():创建文件夹,如果父文件夹不存在,会帮你创建出来
删除功能:public boolean delete()
注意:
  A:如果你创建文件或者文件夹忘了写盘符路径,那么,默认在项目路径下。
  B:Java中的删除不走回收站。
  C:要删除一个文件夹,请注意该文件夹内不能包含文件或者文件夹
重命名功能:public boolean renameTo(File dest)
  如果路径名相同,就是改名。
  如果路径名不同,就是改名并剪切。

路径以盘符开始:绝对路径 c:\\a.txt
 路径不以盘符开始:相对路径 a.txt
判断功能:
public boolean isDirectory():判断是否是目录
public boolean isFile():判断是否是文件
public boolean exists():判断是否存在
public boolean canRead():判断是否可读
public boolean canWrite():判断是否可写
public boolean isHidden():判断是否隐藏
获取功能:
public String getAbsolutePath():获取绝对路径
public String getPath():获取相对路径
public String getName():获取名称
public long length():获取长度。字节数
public long lastModified():获取最后一次的修改时间,毫秒值
获取功能:
public String[] list():获取指定目录下的所有文件或者文件夹的名称数组
public File[] listFiles():获取指定目录下的所有文件或者文件夹的File数组
文件名称过滤器FilenameFilter
要求重写public boolean accept(File dir, String name)方法
public String[] list(FilenameFilter filter)
public File[] listFiles(FilenameFilter filter)
异常:程序出现了不正常的情况。
程序的异常:Throwable
  严重问题:Error 我们不处理。这种问题一般都是很严重的,比如说内存溢出。
  问题:Exception
   编译期问题:不是RuntimeException的异常 必须进行处理的,因为你不处理,编译就不能通过。
   运行期问题:RuntimeException 这种问题我们也不处理,因为是你的问题,而且这个问题出现肯定是我们的代码不够严谨,需要修正代码的。
如何程序出现了问题,我们没有做任何处理,最终jvm会做出默认的处理。
把异常的名称,原因及出现的问题等信息输出在控制台。同时会结束程序。
注意事项:
 1:能明确的尽量明确,不要用大的来处理。
 2:平级关系的异常谁前谁后无所谓,如果出现了子父关系,父必须在后面。
  3.一旦try里面出了问题,就会在这里把问题给抛出去,然后和catch里面的问题进行匹配,
  4.一旦有匹配的,就执行catch里面的处理,然后结束了try...catch,继续执行后面的语句。
JDK7出现了一个新的异常处理方案:
  try{
  }catch(异常名1 | 异常名2 | ...  变量 ) {
   ...
  }
  注意:这个方法虽然简洁,但是也不够好。
   A:处理方式是一致的。(实际开发中,好多时候可能就是针对同类型的问题,给出同一个处理)
   B:多个异常间必须是平级关系。
编译时异常和运行时异常的区别
编译期异常:Java程序必须显示处理,否则程序就会发生错误,无法通过编译
运行期异常:无需显示处理,也可以和编译时异常一样处理
异常中要了解的几个方法:
public String getMessage():异常的消息字符串  
public String toString():返回异常的简单信息描述,此对象的类的 name(全路径名),": "(冒号和一个空格)
  调用此对象 getLocalizedMessage()方法的结果 (默认返回的是getMessage()的内容)
printStackTrace() 获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。把信息输出在控制台。
有些时候,我们是可以对异常进行处理的,但是又有些时候,我们根本就没有权限去处理某个异常。
或者说,我处理不了,我就不处理了。为了解决出错问题,Java针对这种情况,就提供了另一种处理方案:抛出。
格式:
  throws 异常类名
  注意:这个格式必须跟在方法的括号后面。
注意:
  尽量不要在main方法上抛出异常。
  但是我讲课为了方便我就这样做了。
小结:
  编译期异常抛出,将来调用者必须处理。
  运行期异常抛出,将来调用可以不用处理。
throw:如果出现了异常情况,我们可以把该异常抛出,这个时候的抛出的应该是异常的对象。
throws和throw的区别(面试题)
 throws
  用在方法声明后面,跟的是异常类名
  可以跟多个异常类名,用逗号隔开
  表示抛出异常,由该方法的调用者来处理
  throws表示出现异常的一种可能性,并不一定会发生这些异常
 throw
  用在方法体内,跟的是异常对象名
  只能抛出一个异常对象名
  表示抛出异常,由方法体内的语句处理
  throw则是抛出了异常,执行throw则一定抛出了某种异常
finally:被finally控制的语句体一定会执行
注意:如果在执行到finally之前jvm退出了,就不能执行了。
A:格式
  try...catch...finally...
B:用于释放资源,在IO流操作和数据库操作中会见到
 final,finally和finalize的区别
 final:最终的意思,可以修饰类,成员变量,成员方法
  修饰类,类不能被继承
  修饰变量,变量是常量
  修饰方法,方法不能被重写
 finally:是异常处理的一部分,用于释放资源。
   一般来说,代码肯定会执行,特殊情况:在执行到finally之前jvm退出了
 finalize:是Object类的一个方法,用于垃圾回收
 如果catch里面有return语句,请问finally里面的代码还会执行吗?
    如果会,请问是在return前,还是return后。
     会。前。
    准确的说,应该是在中间。
 java不可能对所有的情况都考虑到,所以,在实际的开发中,我们可能需要自己定义异常。
 而我们自己随意的写一个类,是不能作为异常类来看的,要想你的类是一个异常类,就必须继承自Exception或者RuntimeException
两种方式:
A:继承Exception
B:继承RuntimeException
 异常注意事项:
 A:子类重写父类方法时,子类的方法必须抛出相同的异常或父类异常的子类。(父亲坏了,儿子不能比父亲更坏)
 B:如果父类抛出了多个异常,子类重写父类时,只能抛出相同的异常或者是他的子集,子类不能抛出父类没有的异常
 C:如果被重写的方法没有异常抛出,那么子类的方法绝对不可以抛出异常,如果子类方法内有异常发生,那么子类只能try,不能throws
C:异常处理的变形
   try...catch...finally
   try...catch...
   try...catch...catch...
   try...catch...catch...fianlly
   try...finally
递归:方法定义中调用方法本身的现象
 注意事项:
  A:递归一定要有出口,否则就是死递归
  B:递归的次数不能太多,否则就内存溢出
  C:构造方法不能递归使用
案例一:练习File类中的方法

public class FileDemo {
 public static void main(String[] args) {
  File file = new File("E:\\demo\\a.txt");根据一个路径得到File对象,
  File file2 = new File("E:\\demo", "a.txt");根据一个目录和一个子文件/目录得到File对象
  File file3 = new File("e:\\demo");
  File file4 = new File(file3, "a.txt");根据一个父File对象和一个子文件/目录得到File对象
  // 以上三种方式其实效果一样
  File file = new File("e:\\demo");
  System.out.println("mkdir:" + file.mkdir());我要在e盘目录下创建一个文件夹demo
  File file2 = new File("e:\\demo\\a.txt");
  System.out.println("createNewFile:" + file2.createNewFile());我要在e盘目录demo下创建一个文件a.txt
  // 注意:要想在某个目录下创建内容,该目录首先必须存在。
  File file3 = new File("e:\\test\\b.txt");
  System.out.println("createNewFile:" + file3.createNewFile());我要在e盘目录test下创建一个文件b.txt
  File file4 = new File("e:\\test\\aaa");
  System.out.println("mkdir:" + file4.mkdir());我要在e盘目录test下创建aaa目录
  File file5 = new File("e:\\test");
  File file6 = new File("e:\\test\\aaa");
  System.out.println("mkdir:" + file5.mkdir());
  System.out.println("mkdir:" + file6.mkdir());我要在e盘目录test下创建aaa目录
  // 其实我们有更简单的方法
  File file7 = new File("e:\\aaa\\bbb\\ccc\\ddd");
  System.out.println("mkdirs:" + file7.mkdirs());
  // 看下面的这个东西:
  File file8 = new File("e:\\liuyi\\a.txt");
  System.out.println("mkdirs:" + file8.mkdirs());
  // 删除功能:我要删除aaa文件夹
  File file9 = new File("aaa\\bbb");
  File file10 = new File("aaa");
  System.out.println("delete:" + file6.delete());
  System.out.println("delete:" + file7.delete());
  // 删除功能:我要删除a.txt这个文件
  File file11 = new File("a.txt");
  System.out.println("delete:" + file11.delete());
  // 创建一个文件对象
  File file = new File("哈士奇.jpg");
  // 需求:我要修改这个文件的名称为"藏獒.jpg"
  File newFile = new File("藏獒.jpg");
  System.out.println("renameTo:" + file.renameTo(newFile));
  // 创建文件对象
  File file = new File("a.txt");
  System.out.println("isDirectory:" + file.isDirectory());// false
  System.out.println("isFile:" + file.isFile());// true
  System.out.println("exists:" + file.exists());// true
  System.out.println("canRead:" + file.canRead());// true
  System.out.println("canWrite:" + file.canWrite());// true
  System.out.println("isHidden:" + file.isHidden());// false
  // 创建文件对象
  File file = new File("demo\\test.txt");
  System.out.println("getAbsolutePath:" + file.getAbsolutePath());
  System.out.println("getPath:" + file.getPath());
  System.out.println("getName:" + file.getName());
  System.out.println("length:" + file.length());
  System.out.println("lastModified:" + file.lastModified());// 1416471971031
  Date d = new Date(1416471971031L);
  SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  String s = sdf.format(d);
  System.out.println(s);
  // 指定一个目录
  File file = new File("e:\\");
  String[] strArray = file.list();获取指定目录下的所有文件或者文件夹的名称数组
  for (String s : strArray) {
   System.out.println(s);
  }
  File[] fileArray = file.listFiles();获取指定目录下的所有文件或者文件夹的File数组
  for (File f : fileArray) {
   System.out.println(f.getName());
  }
 }
}



案例二:判断E盘目录下是否有后缀名为.jpg的文件,如果有,就输出此文件名称

分析:
  A:封装e判断目录
  B:获取该目录下所有文件或者文件夹的File数组
  C:遍历该File数组,得到每一个File对象,然后判断
  D:是否是文件
   是:继续判断是否以.jpg结尾
    是:就输出该文件名称
    否:不搭理它
   否:不搭理它
public class FileDemoOne {
 public static void main(String[] args) {
  // 封装e判断目录
  File file = new File("e:\\");
  // 获取该目录下所有文件或者文件夹的File数组
  File[] fileArray = file.listFiles();
  // 遍历该File数组,得到每一个File对象,然后判断
  for (File f : fileArray) {
   // 是否是文件
   if (f.isFile()) {
    // 继续判断是否以.jpg结尾
    if (f.getName().endsWith(".jpg")) {
     // 就输出该文件名称
     System.out.println(f.getName());
    }
   }
  }
 }
}



案例三:判断E盘目录下是否有后缀名为.jpg的文件,如果有,就输出此文件名称
 

A:先获取所有的,然后遍历的时候,依次判断,如果满足条件就输出。
 B:获取的时候就已经是满足条件的了,然后输出即可。
public class FileDemoTwo {
 public static void main(String[] args) {
  // 封装e判断目录
  File file = new File("e:\\");
  // 获取该目录下所有文件或者文件夹的String数组
  // public String[] list(FilenameFilter filter)
  String[] strArray = file.list(new FilenameFilter() {
   @Override
   public boolean accept(File dir, String name) {
    return new File(dir, name).isFile() && name.endsWith(".jpg");
   }
  });
  // 遍历
  for (String s : strArray) {
   System.out.println(s);
  }
 }
}



案例四:把E:\评书\三国演义下面的视频名称修改为00?_介绍.avi

思路:
  A:封装目录
  B:获取该目录下所有的文件的File数组
  C:遍历该File数组,得到每一个File对象
  D:拼接一个新的名称,然后重命名即可。
public class FileDemo {
 public static void main(String[] args) {
  // 封装目录
  File srcFolder = new File("E:\\评书\\三国演义");
  // 获取该目录下所有的文件的File数组
  File[] fileArray = srcFolder.listFiles();
  // 遍历该File数组,得到每一个File对象
  for (File file : fileArray) {
   // System.out.println(file);
   // E:\评书\三国演义\三国演义_001_[评书网-今天很高兴,明天就IO了]_桃园三结义.avi
   // 改后:E:\评书\三国演义\001_桃园三结义.avi
   String name = file.getName(); // 三国演义_001_[评书网-今天很高兴,明天就IO了]_桃园三结义.avi
   int index = name.indexOf("_");
   String numberString = name.substring(index + 1, index + 4);
   int endIndex = name.lastIndexOf('_');
   String nameString = name.substring(endIndex);
   String newName = numberString.concat(nameString); // 001_桃园三结义.avi
   File newFile = new File(srcFolder, newName); // E:\\评书\\三国演义\\001_桃园三结义.avi
   // 重命名即可
   file.renameTo(newFile);
  }
 }
}



案例五:递归删除带内容的目录

分析:
  A:封装目录
  B:获取该目录下的所有文件或者文件夹的File数组
  C:遍历该File数组,得到每一个File对象
  D:判断该File对象是否是文件夹
   是:回到B
   否:就删除
public class FileDeleteDemo {
 public static void main(String[] args) {
  // 封装目录
  File srcFolder = new File("demo");
  // 递归实现
  deleteFolder(srcFolder);
 }
 private static void deleteFolder(File srcFolder) {
  // 获取该目录下的所有文件或者文件夹的File数组
  File[] fileArray = srcFolder.listFiles();
  if (fileArray != null) {
   // 遍历该File数组,得到每一个File对象
   for (File file : fileArray) {
    // 判断该File对象是否是文件夹
    if (file.isDirectory()) {
     deleteFolder(file);
    } else {
     System.out.println(file.getName() + "---" + file.delete());
    }
   }
   System.out.println(srcFolder.getName() + "---" + srcFolder.delete());
  }
 }
}



案例六:请大家把E:\JavaSE目录下所有的java结尾的文件的绝对路径给输出在控制台。

分析:
  A:封装目录
  B:获取该目录下所有的文件或者文件夹的File数组
  C:遍历该File数组,得到每一个File对象
  D:判断该File对象是否是文件夹
   是:回到B
   否:继续判断是否以.java结尾
    是:就输出该文件的绝对路径
    否:不搭理它
public class FilePathDemo {
 public static void main(String[] args) {
  // 封装目录
  File srcFolder = new File("E:\\JavaSE");
  // 递归功能实现
  getAllJavaFilePaths(srcFolder);
 }
 private static void getAllJavaFilePaths(File srcFolder) {
  // 获取该目录下所有的文件或者文件夹的File数组
  File[] fileArray = srcFolder.listFiles();
  // 遍历该File数组,得到每一个File对象
  for (File file : fileArray) {
   // 判断该File对象是否是文件夹
   if (file.isDirectory()) {
    getAllJavaFilePaths(file);
   } else {
    // 继续判断是否以.java结尾
    if (file.getName().endsWith(".java")) {
     // 就输出该文件的绝对路径
     System.out.println(file.getAbsolutePath());
    }
   }
  }
 }
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值