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
注意
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();
}
}
}