黑马程序员---Java异常和文件

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-

2015.10.9

目录:
1. 异常
2. 文件
3. Files


1. 异常

异常指程序在某些情况下,发生不正常的状况。比如程序本身的错误如空指针异常,或是程序无法预料的异常如IO中,读取某个文件却找不到它,这时候就会发生FileNotFoundException异常。

1.1异常的分类
Throwable 类是 Java 语言中所有错误或异常的超类。只有当对象是此类(或其子类之一)的实例时,才能通过 Java 虚拟机或者 Java throw 语句抛出。类似地,只有此类或其子类之一才可以是 catch 子句中的参数类型。

(1)Error

用于指示合理的应用程序不应该试图捕获的严重问题。大多数这样的错误都是异常条件。
此异常无需处理,因为这些错误可能是再也不会发生的异常条件,或者应用程序本身无法处理此类问题。

(2) Exception

  • RuntimeException运行时期异常是那些可能在 Java 虚拟机正常运行期间抛出的异常的超类。
    例如:数组越界异常IndexOutOfBoundsException

    注意:此类异常一般是由于代码不够严谨所造成。

  • 编译期异常
    非运行时期异常即为此类异常。比如IOException
    注意:此类异常必须解决才能使程序继续运行。

1.2 异常的捕获

(1)对于RuntimeException,可以通过代码检查来避免。
例如:除数为零的情况

// 除数为0
    int i = 0;
    int j = 9;
    //这里先对除数i进行一个判断
    if (i != 0) {
        int r = j / i;
    }

(2)编译期异常的处理
方法一:对可能产生异常的代码,使用try-catch-finally语句处理
格式如下:

try{
    //可能产生异常的语句
}catch(异常类名1 异常类变量){
    //处理语句
}catch(异常类名2异常类变量){
    //处理语句
}
finally{
    //处理语句
}

catch语句可以有若干个,catch语句中的异常类名从前往后只能是平级关系或者继承关系。
例如:

try{
    //可能产生异常的语句
}catch(Exception e){
    //处理语句
}

Exception是编译期异常的超类,所以该catch语句可以捕获所有编译期异常。
finally语句一定会被执行,除非到达finally语句之前JVM停止运行。

除了以上这种形式外,可以使用只包含try-catch、try-finally形式。

Java 7.0中,异常处理的改进
- 异常多重捕获
可以在单个catch块中处理多个同级别的异常,异常之间用“|”隔开。

        ```
        try{
            可能产生异常的语句...
            //注意此处多个异常类名只能是平级关系
        }catch(异常类名1|异常类名2|异常类名3 异常类变量){
            //处理语句...
        }
        ```

    - try-with-resources
        该语句可以在try块中创建实现了Closeable接口的对象。之后无需显示关闭该资源,try块会自动关闭它。

注意:try语句越少越好,执行它会耗费额外的资源,容易使程序变慢。

常见问题:try-catch-finally语句的return或throw问题

例如:以下这个代码将返回0,所以finally中的赋值并不会影响return的值。

    int i=0;
    try{
        return i;
    }finally{
        i=9;
    }

分析:执行到try中的return语句时,发现包含finally语句,如果finally语句块中没有return,先暂停try中return去执行finally块,然后返回return原来的值,如果finally中有return,那么原来的return将被覆盖,即运行finally语句中的return立即退出方法。同理throw也一样。

try-catch-finally语句的规范化

使用try-catch-finally语句的时候经常会遇到有多种异常需要处理,同时还有资源需要关闭。这时候可以使用嵌套的try-catch-finally语句来保持代码的层次性和简洁性。在Java 7.0以后,可以使用改进的try-with-resources语句来处理资源的关闭和异常,大大简化了异常的处理。

如下:

InputStream in = new FileInputStream("adc.jf");
//在外层try语句中处理异常
try {
    //在内层try语句中进行操作并保证资源关闭
    try {
        in.read();
    } finally {
        in.close();
    }
} catch (Exception e) {
    //异常处理代码
}

方法二:在方法声明中抛出异常
格式:在方法声明末尾使用关键字throws+异常类名来声明抛出异常
如:

public void show() throws Exception{
    //代码
}

注意:throws 后可以跟多个异常类名。

异常声明注意:

  • 子类重写父类的方法时,如果父类有异常抛出,子类必须抛出相同的或者父类异常的子类。如果父类无异常抛出,则子类不能抛出异常。
  • 子类同时有继承和实现,那么抛出的异常是两者的交集。

1.3 自定义异常类

异常类只有声明为Exception的子类才能被使用。
我们可以通过扩展异常类来创建自己的异常类
例如:

public class MyException extends Exception{
    public MyException(String massage){
        super(massage);
    } 
}

1.4 异常类的方法
public void printStackTrace() //将此 throwable 及其追踪输出至标准错误流。
例如:

try{
    //此处抛出一个异常
    throw new Exception();
}catch(Exception e){
    //调用printStackTrace方法
    e.printStackTrace();
}

1.5 异常链
Java1.4 中每个Throwable可以有一个cause,同时cause自身也会有cause,即每个异常都是由另一个异常引起的,这样就形成了异常链。

2. File

Java中文件和目录路径名的抽象表示形式。

2.1 新建File对象

  • 通过将给定路径名字符串转换为抽象路径名来创建一个新 File 实例

    File f1=new File("c:\\Users\\11\\Desktop\\设计模式.txt");
    
  • 根据 parent 抽象路径名和 child 路径名字符串创建一个新 File 实例

    File parent=new File("c:\\Users\\11\\Desktop");
    File f2=new File(parent,"设计模式.txt");
    
  • 根据 parent 路径名字符串和 child 路径名字符串创建一个新 File 实例

    File f3=new File(“c:\Users\11\Desktop”,”设计模式.txt”);

(2)创建文件和目录

方法1:当不存在具有此抽象路径名指定名称的文件时创建一个新的空文件:

File f=new File("C:\\Users\\郭仪雄\\Desktop\\File2.txt");
//当f不存在时创建
if(!f.exists()){
    //新建f文件
    f.createNewFile();
}

方法2:创建一个新的空文件夹

使用File.mkdir() 或者File.mkdirs()。
后者将创建此抽象路径名指定的目录,包括所有必需但不存在的父目录

(3)查询File文件

相关方法:

File.length() 查询此抽象路径名表示的文件的长度。

File.isFile() 查询此抽象路径名表示的文件是否是一个标准文件

File.exists() 查询此此抽象路径名表示的文件或文件夹是否存在

File.isDirectory() 测试此抽象路径名表示的文件是否是一个目录

File.isHidden() 测试此抽象路径名指定的文件是否是一个隐藏文件

File.canRead() 测试应用程序是否可以读取此抽象路径名表示的文件

File.canWrite() 测试应用程序是否可以修改此抽象路径名表示的文件

(4)获取文件

File.listFiles() 返回一个抽象路径名数组,这些路径名表示此抽象路径名表示的目录中的文件,通过遍历此数组即可获取File。

File.listFiles(FilenameFilter filter) 返回抽象路径名数组,这些路径名表示此抽象路径名表示的目录中满足指定过滤器的文件和目录
实现此接口的类实例可用于过滤器文件名。Abstract Window Toolkit 的文件对话框组件使用这些实例过滤 File 类的 list 方法中的目录清单。
例如一个过滤txt类型文件的匿名内部类实现

//新建文件夹File对象
File file=new File("d:\\学习资料");
//抽象路径名数组,只包含了能通过调节的文件
File[] list=file.listFiles(new FilenameFilter(){
    //重写的accept()
    public boolean accept(File dir,String name){
        return new File(dir,name).isFile()&&name.endsWith(".txt");
    }
});

File.getAbsolutePath() 返回此抽象路径名的绝对路径名字符串

File.getPath() 将此抽象路径名转换为一个路径名字符串

File.getName() 返回由此抽象路径名表示的文件或目录的名称

File.getParent() 返回此抽象路径名父目录的路径名字符串,如果此路径名没有指定父目录,则返回 null

public File getParentFile() 返回此抽象路径名父目录的抽象路径名

(5)重命名
File.renameTo(File dest) 重新命名此抽象路径名表示的文件
(6)删除功能
File.delete() 注意此方法要成功需保证当此表示目录时为空目录

2.2 递归复制多级目录

//这是一个复制多级文件夹的方法
public static void copy(String src, String target) throws IOException {
    //把传入的path包装成File对象
    File srcFile = new File(src);
    File tarFile = new File(target);
    //如果是文件,则复制
    if (srcFile.isFile()) {
        //判断目标文件夹是否存在
        if (!tarFile.exists()) {
            //不存在则创建
            tarFile.mkdirs();
        }
        //创建字节流对象
        FileInputStream fis = new FileInputStream(srcFile);
        FileOutputStream fos = new FileOutputStream(new File(target, srcFile.getName()));
        byte[] bys = new byte[1024];
        //进行复制
        while (fis.read(bys) != -1) {
            fos.write(bys, 0, bys.length);
        }
        //释放资源
        fis.close();
        fos.close();

    } else {//如果是文件夹,则递归    
        //创建目标文件夹File对象
        File desk = new File(target, srcFile.getName());
        //获取当前文件夹File数组
        File[] list = srcFile.listFiles();
        //循环复制
        for (File f : list) {
            //此处进行了递归
            copy(f.getPath(), desk.getPath());
        }

    }

}

3 Files

这是文件的工具类,包含了大量的操作文件的方法,同时提供了路径Path和File转换的API。

3.1Path

Path表示的是一个目录名序列,可以跟一个文件名。
Path的创建:

Paths.get("rootDir","folderName","fileName");
//get方法接受多个字符串,以系统的路径分隔符连接起来,然后解析连接起来的结果。

3.2 Files类的使用

新建文件或目录

  • Path createFile(Path p)
  • Path createDirectory(Path p)
  • Path createDirectories(Path p)
  • Path createTempFile(String prefix,String )
  • static File createTempFile(String prefix, String suffix)
    在默认临时文件目录中创建一个空文件,使用给定前缀和后缀生成其名称。
  • static File createTempFile(String prefix, String suffix, File directory)
    在指定目录中创建一个新的空文件,使用给定的前缀和后缀字符串生成其名称。

写入到指定文件

  • Files.write(Path path, List,Charset.forName(“gbk”))
    注意,会覆盖调!

删除文件

  • boolean deleteIfExists(Path path)
    如果存在则删除

复制文件

  • static copy(Path source,OutputStream os)
    source 被复制的文件路径

  • static copy(source, target,option)
    只能复制文件,source、target是文件路径名

    Option:

    • StandardCopyOption.ATOMIC_MOVE
      进行原子性复制,将会保证复制成功或者保持在原来位置
    • StandardCopyOption.COPY_ATTRIBUTES
      复制所有属性
    • StandardCopyOption.REPLACE_EXISTING
      如果存在则替换

移动方法

  • move()

迭代目录

  • Files.newDirectoryStream(newPath)
  • Files.newDirectoryStream(Path dir, String glob)
    获取一个目录流,使用迭代器迭代。try语句确保关闭流。

    //获取要迭代的目录路径
    Path newPath = Paths.get("c:", "Users", "11", "Desktop", "测试");
    //使用try-with-resources语句确保资源的关闭
    try (DirectoryStream<Path> entries = Files.newDirectoryStream(newPath,"*.txt");) {
        **使用for each遍历**
        for (Path d : entries)
            System.out.println(d);
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值