try-catch-finally

finally
放在try-catch后面的,无论是正常执行还是异常执行代码,最后一定要执行,除非JVM退出。一般用于进行最后的资源释放操作。

try-catch-finally格式

try {
    FileOutputStream fos = new FileOutputStream("a.txt");
    fos.write(97); 
} catch (IOException e) {
    e.printStackTrace();
}finally{

}

在关闭资源时,应先判读资源是否为空(null)。

import java.io.*;

/**
 *   目标:学会使用finally释放资源。
 */
public class TryCatchFinallyDemo1 {
    public static void main(String[] args) {
        InputStream is = null;
        OutputStream os = null;
        try {
            // 1、创建一个字节输入流管道与原文件接通
             is = new FileInputStream("file-io-app/src/out04.txt");

            // 2、创建一个字节输出流管道与目标文件接通
             os = new FileOutputStream("file-io-app/src/out05.txt");

            // 3、定义一个字节数组转移数据
            byte[] buffer = new byte[1024];
            int len; // 记录每次读取的字节数。
            while ((len = is.read(buffer)) != -1){
                os.write(buffer, 0 , len);
            }
            System.out.println("复制完成了!");

         //   System.out.println( 10 / 0);

        } catch (Exception e){
            e.printStackTrace();
        } finally {
            // 无论代码是正常结束,还是出现异常都要最后执行这里
            System.out.println("========finally=========");
            try {
                // 4、关闭流。
                if(os!=null)os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(is != null) is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        System.out.println(test(10, 2));
    }

    public static int test(int a , int b){
        try {
            int c = a / b;
            return c;
        }catch (Exception e){
            e.printStackTrace();
            return -111111; // 计算出现bug.
        }finally {
            System.out.println("--finally--");
            // 哪怕上面有return语句执行,也必须先执行完这里才可以!
            // 开发中不建议在这里加return ,如果加了,返回的永远是这里的数据了,这样会出问题!
            return 100;
        }
    }
}

try-with-resource

java gdal 释放资源 java如何手动释放资源_System

注意

java gdal 释放资源 java如何手动释放资源_java_02

import java.io.*;

public class TryCatchResouceDemo2 {
    public static void main(String[] args) {

        try (
                // 这里面只能放置资源对象,用完会自动关闭:自动调用资源对象的close方法关闭资源(即使出现异常也会做关闭操作)
                // 1、创建一个字节输入流管道与原视频接通
               InputStream is = new FileInputStream("file-io-app/src/out04.txt");
                // 2、创建一个字节输出流管道与目标文件接通
               OutputStream os = new FileOutputStream("file-io-app/src/out05.txt");

               // int age = 23; // 这里只能放资源
                MyConnection connection = new MyConnection(); // 最终会自动调用资源的close方法
                ) {

            // 3、定义一个字节数组转移数据
            byte[] buffer = new byte[1024];
            int len; // 记录每次读取的字节数。
            while ((len = is.read(buffer)) != -1){
                os.write(buffer, 0 , len);
            }
            System.out.println("复制完成了!");

        } catch (Exception e){
            e.printStackTrace();
        }

    }
}

class MyConnection implements AutoCloseable{
    @Override
    public void close() throws IOException {
        System.out.println("连接资源被成功释放了!");
    }
}
import java.io.*;

public class TryCatchResouceDemo3 {
    public static void main(String[] args) throws Exception {

        // 这里面只能放置资源对象,用完会自动关闭:自动调用资源对象的close方法关闭资源(即使出现异常也会做关闭操作)
        // 1、创建一个字节输入流管道与原视频接通
        InputStream is = new FileInputStream("file-io-app/src/out04.txt");
        // 2、创建一个字节输出流管道与目标文件接通
        OutputStream os = new FileOutputStream("file-io-app/src/out05.txt");
        try ( is ; os ) {
            // 3、定义一个字节数组转移数据
            byte[] buffer = new byte[1024];
            int len; // 记录每次读取的字节数。
            while ((len = is.read(buffer)) != -1){
                os.write(buffer, 0 , len);
            }
            System.out.println("复制完成了!");

        } catch (Exception e){
            e.printStackTrace();
        }
    }
}

案例

需求:
将某个磁盘的文件夹拷贝到另一个文件夹下去,包括文件夹中的全部信息

代码示例

import java.io.*;

public class Test4 {
    public static void main(String[] args) {
         // D:\resources
        copy(new File("D:\\resources") , new File("D:\\new"));
    }

    public static void copy(File src , File dest){
        // 1、判断源目录是否存在
        if(src!= null && src.exists() && src.isDirectory()){
            // 2、目标目录需要创建一下  D:\new\resources
            File destOne = new File(dest , src.getName());
            destOne.mkdirs();

            // 3、提取原目录下的全部一级文件对象
            File[] files = src.listFiles();
            // 4、判断是否存在一级文件对象
            if(files != null && files.length > 0) {
                // 5、遍历一级文件对象
                for (File file : files) {
                    // 6、判断是文件还是文件夹,是文件直接复制过去
                    if(file.isFile()){
                        copyFile(file, new File(destOne , file.getName()));
                    }else {
                        // 7、当前遍历的是文件夹,递归复制
                        copy(file, destOne);
                    }
                }
            }

        }
    }

    public static void copyFile(File srcFile, File destFile){
        try (
                // 1、创建一个字节输入流管道与原视频接通
                InputStream is = new FileInputStream(srcFile);
                // 2、创建一个字节输出流管道与目标文件接通
                OutputStream os = new FileOutputStream(destFile);
                ) {
            // 3、定义一个字节数组转移数据
            byte[] buffer = new byte[1024];
            int len; // 记录每次读取的字节数。
            while ((len = is.read(buffer)) != -1){
                os.write(buffer, 0 , len);
            }
        } catch (Exception e){
            e.printStackTrace();
        }
    }
}