Top

JAVA SE02 Unit03

  1. 将日志信息写入文本文件
  2. 读取一个文本文件的所有行输出到控制台
  3. FileUtils实现文件复制功能(包含异常的处理)
  4. 测试常见的RuntimeException
  5. FileUtils实现文件复制功能(抛出自定义的文件复制异常)

1 将日志信息写入文本文件

1.1 问题

生成一个文本文件 pw.txt,用于记录多行日志信息。pw.txt 文件的内容如图-1所示:

图-1

1.2 步骤

实现此案例需要按照如下步骤进行。

步骤一:新建TestPrintWriter类,添加测试方法testPrintWriter方法

首先,新建名为TestPrintWriter的类,并在类中添加单元测试方法 testPrintWriter。代码如下所示:

import java.io.PrintWriter;
import org.junit.Test;

/**
 * 测试缓冲字符输出流
 *
 */
public class TestPrintWriter {
	/**
	 * 测试缓冲字符输出流
	 * @throws Exception
	 */
	@Test
	public void testPrintWriter()throws Exception{
		
	}
}

步骤二:将多行文本写入文件

PrintWriter是带有行刷新的缓冲字符输出流,它提供了丰富的重载print与println方法。其中,println方法在于输出目标数据后自动输出一个系统支持的换行符。

为向文本文件中写入多行日志信息,首先需要创建一个 PrintWriter类的对象,用于写入文件,然后调用 println 方法写入文本,最后关闭PrintWriter对象。代码如下所示:

import java.io.PrintWriter;
import org.junit.Test;

/**
 * 测试缓冲字符输出流
 *
 */
public class TestPrintWriter {
	/**
	 * 测试缓冲字符输出流
	 * @throws Exception
	 */
	@Test
	public void testPrintWriter()throws Exception{
#cold_bold		PrintWriter pw = new PrintWriter("pw.txt");		
#cold_bold		pw.println("大家好!");
#cold_bold		pw.println("hello!");
#cold_bold		pw.println("bye!");
#cold_bold		pw.close();
	}
}

步骤三:测试

运行testPrintWriter方法,将在当前工程下生成一个名为 pw.txt 的文件,打开该文件,文件中的内容和图-1相同。

1.3 完整代码

本案例的完整代码如下所示:

import java.io.PrintWriter;
import org.junit.Test;

/**
 * 测试缓冲字符输出流
 *
 */
public class TestPrintWriter {
	/**
	 * 测试缓冲字符输出流
	 * @throws Exception
	 */
	@Test
	public void testPrintWriter()throws Exception{
		PrintWriter pw = new PrintWriter("pw.txt");
		
		pw.println("大家好!");
		pw.println("hello!");
		pw.println("bye!");
		pw.close();
	}
}

2 读取一个文本文件的所有行输出到控制台

2.1 问题

读取上一个案例中所创建的文本文件中的内容,并逐行打印显示,效果如图-2所示:

图-2

2.2 方案

首先需要创建文件字节输入流FileInputStream,用于读入文件,代码如:

FileInputStream fis = new FileInputStream("pw.txt");

然后使用所创建的文件字节输入流对象作为参数,构建InputStreamReader类的对象,用于将字节流变为字符流,代码如:

InputStreamReader isr = new InputStreamReader(fis);

再使用所创建的字符输入流对象作为参数,创建BufferedReader类的对象,用于逐行读取文本文件的所有行,代码如:

BufferedReader br = new BufferedReader(isr);

随后,调用 BufferedReader的 readLine方法读取一行文本。需要注意的是,如果因已到达流末尾而没有可读的内容,readLine 则返回null。因此,需要构建 while 循环来逐一读取文件中的每行文本,代码如:

String line = null;
while((line = br.readLine())!=null){
}

2.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:新建TestBufferedReader类,添加测试方法testBufferedReader方法

首先,新建名为TestBufferedReader的类,并在类中添加单元测试方法 testBufferedReader。代码如下所示:

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import org.junit.Test;

/**
 * 测试缓冲字符输入流
 *
 */
public class TestBufferedReader {
	/**
	 * 使用缓冲字符输入流读取文本文件
	 * @throws Exception
	 */
	@Test
	public void testBufferedReader()throws Exception{
		
	}
}

步骤二:读取文本文件的所有行

创建BufferedReader类的对象,并调用该对象的 readLine 方法逐一读取文件中的每行文本并打印显示。注意:使用完毕后,需要关闭BufferedReader对象。

代码如下所示:

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import org.junit.Test;

/**
 * 测试缓冲字符输入流
 *
 */
public class TestBufferedReader {
	/**
	 * 使用缓冲字符输入流读取文本文件
	 * @throws Exception
	 */
	@Test
	public void testBufferedReader()throws Exception{
#cold_bold		FileInputStream fis = new FileInputStream("pw.txt");
#cold_bold		InputStreamReader isr = new InputStreamReader(fis);
#cold_bold		BufferedReader br = new BufferedReader(isr);
#cold_bold		
#cold_bold		String line = null;
#cold_bold		while((line = br.readLine())!=null){
#cold_bold			System.out.println(line);
#cold_bold		}
#cold_bold		
#cold_bold		br.close();
	}
}

步骤三:测试

运行testBufferedReader方法,将逐行打印显示文件中的内容。

2.4 完整代码

本案例的完整代码如下所示:

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import org.junit.Test;

/**
 * 测试缓冲字符输入流
 *
 */
public class TestBufferedReader {
	/**
	 * 使用缓冲字符输入流读取文本文件
	 * @throws Exception
	 */
	@Test
	public void testBufferedReader()throws Exception{
		FileInputStream fis = new FileInputStream("pw.txt");
		InputStreamReader isr = new InputStreamReader(fis);
		BufferedReader br = new BufferedReader(isr);
		
		String line = null;
		while((line = br.readLine())!=null){
			System.out.println(line);
		}
		
		br.close();
	}
}

3 FileUtils实现文件复制功能(包含异常的处理)

3.1 问题

创建工具类 FileUtils,为其定义文件复制方法,实现文件复制功能,并添加异常处理机制。

3.2 方案

前面的案例中,已经描述过文件复制功能的实现,此案例需要为其添加异常处理机制,用来处理复制过程中的各种异常情况,如需要复制的文件不存在等。

需要使用 try 语句捕获代码可能会产生的异常对象,并使用 catch语句对异常做相应的处理。每个try语句块可以伴随一个或多个catch语句,用于处理可能产生的不同类型的异常,代码如下所示:

		FileInputStream fis = null;
		FileOutputStream fos = null;
try {
			//...  代码
		} catch (FileNotFoundException e) {
			System.err.println("文件没有找到");
			e.printStackTrace();
		} catch (IOException e) {
			System.err.println("读写异常");
			e.printStackTrace();
		}

上述代码中,可以捕获处理FileNotFoundException异常,以及 IOException。

finally语句为异常处理提供一个统一的出口,通常在finally语句中可以进行资源的消除工作,如关闭打开的文件、删除临时文件等。代码如下所示:

		FileInputStream fis = null;
		FileOutputStream fos = null;
		try {
			//... 代码
		} catch (FileNotFoundException e) {
			//... 处理异常的代码
		} catch (IOException e) {
			//...处理异常的代码
		} finally {
			if (fis != null) {
				try {
					fis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (fos != null) {
				try {
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

3.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:新建FileUtils类,添加测试方法testCopy方法

首先,新建名为FileUtils的类,并在类中添加单元测试方法 testCopy。代码如下所示:

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import org.junit.Test;

public class FileUtils {
	/**
	 * 对复制文件的代码添加异常捕获机制
	 */
	@Test
	public void testCopy() {
		
	}
}

步骤二:实现文件复制功能

为方法testCopy添加代码,实现文件复制功能,代码如下所示:

public void testCopy() {
#cold_bold		FileInputStream fis = null;
#cold_bold		FileOutputStream fos = null;
#cold_bold		fis = new FileInputStream("fos.dat");
#cold_bold		fos = new FileOutputStream("fos_copy4.dat");
#cold_bold		int d = -1;
#cold_bold		while ((d = fis.read()) != -1) {
#cold_bold			fos.write(d);
#cold_bold		}
#cold_bold		System.out.println("复制完毕");		
	}

步骤三:捕获并处理异常

为上一步骤中的代码添加 try/catch 语句,以实现异常的处理。

先处理 FileNotFoundException 异常,然后处理 IOException 异常,代码如下所示:

public void testCopy() {
		FileInputStream fis = null;
		FileOutputStream fos = null;
#cold_bold		try {
			fis = new FileInputStream("fos.dat");
			fos = new FileOutputStream("fos_copy4.dat");
			int d = -1;
			while ((d = fis.read()) != -1) {
				fos.write(d);
			}
			System.out.println("复制完毕");
#cold_bold		} catch (FileNotFoundException e) {
#cold_bold			System.err.println("文件没有找到");
#cold_bold			e.printStackTrace();
#cold_bold		} catch (IOException e) {
#cold_bold			System.err.println("读写异常");
#cold_bold			e.printStackTrace();
#cold_bold		} 
	}

步骤四:资源清理

使用 finally 语句释放相关资源,代码如下所示:

public void testCopy() {
		FileInputStream fis = null;
		FileOutputStream fos = null;
		try {
			fis = new FileInputStream("fos.dat");
			fos = new FileOutputStream("fos_copy4.dat");
			int d = -1;
			while ((d = fis.read()) != -1) {
				fos.write(d);
			}
			System.out.println("复制完毕");
		} catch (FileNotFoundException e) {
			System.err.println("文件没有找到");
			e.printStackTrace();
		} catch (IOException e) {
			System.err.println("读写异常");
			e.printStackTrace();
#cold_bold		} finally {
#cold_bold			if (fis != null) {
#cold_bold				try {
#cold_bold					fis.close();
#cold_bold				} catch (IOException e) {
#cold_bold					e.printStackTrace();
#cold_bold				}
#cold_bold			}
#cold_bold			if (fos != null) {
#cold_bold				try {
#cold_bold					fos.close();
#cold_bold				} catch (IOException e) {
#cold_bold					e.printStackTrace();
#cold_bold				}
#cold_bold			}
#cold_bold		}
	}

步骤五:测试

运行testCopy方法,如果当前工程目录下没有文件fos.dat,则将产生FileNotFoundException 异常。

3.4 完整代码

本案例中,类FileUtils的完整代码如下所示:

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import org.junit.Test;

public class FileUtils {
	/**
	 * 对复制文件的代码添加异常捕获机制
	 */
	@Test
	public void testCopy() {
		FileInputStream fis = null;
		FileOutputStream fos = null;
		try {
			fis = new FileInputStream("fos.dat");
			fos = new FileOutputStream("fos_copy4.dat");
			int d = -1;
			while ((d = fis.read()) != -1) {
				fos.write(d);
			}
			System.out.println("复制完毕");
		} catch (FileNotFoundException e) {
			System.err.println("文件没有找到");
			e.printStackTrace();
		} catch (IOException e) {
			System.err.println("读写异常");
			e.printStackTrace();
		} finally {
			if (fis != null) {
				try {
					fis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (fos != null) {
				try {
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

4 测试常见的RuntimeException

4.1 问题

写代码,制造常见的RuntimeException异常,详细要求如下:

1)制造空指针异常NullPointerException;

2)制造数组越界异常ArrayIndexOutOfBoundsException;

3)制造数学异常ArithmeticException;

4)制造强制类型转换异常ClassCastException;

5)制造数值格式化异常NumberFormatException

4.2 步骤

实现此案例需要按照如下步骤进行。

步骤一:新建类

新建类TestRuntimeException,代码如下所示:

/**
 * 测试常见的运行时异常
 */
public class TestRuntimeException {
}

步骤二:制造空指针异常

当一个引用的值为null的时候,如果通过引用访问对象成员变量或者调用方法,此时,会产生NullPointerException。在此,首先创建测试方法testNullPointerException;然后,将String类的引用str赋值为null;最后,调用String类的length方法即会发生空指针异常,代码如下所示:

import org.junit.Test;

/**
 * 测试常见的运行时异常
 */
public class TestRuntimeException {
#cold_bold	/**
#cold_bold	 * 测试空指针异常
#cold_bold	 */
#cold_bold	@Test
#cold_bold	public void testNullPointerException(){
#cold_bold		String str = null;
#cold_bold		//会引发空指针异常
#cold_bold		System.out.println(str.length());
#cold_bold	}
}

运行testNullPointerException方法,在JUnit视图下会显示抛出了空指针异常,如图-3所示。

图- 3

步骤三:制造数组下标越界异常

如果使用为负或大于等于数组大小的索引来访问数组时抛出的异常。在此,首先创建测试方法testArrayIndexOutOfBoundsException;然后,使用String类的getBytes方法返回字符串“hello”对应的字符数组;最后,输出该字符数组中索引为字符数组长度的字符,此操作即会发生数组下标越界异常,代码如下所示:

import org.junit.Test;
/**
 * 测试常见的运行时异常
 */
public class TestRuntimeException {
	/**
	 * 测试空指针异常
	 */
	@Test
	public void testNullPointerException(){
		//...(代码略)
	}
#cold_bold	/**
#cold_bold	 * 测试数组下标越界异常
#cold_bold	 */
#cold_bold	@Test
#cold_bold	public void testArrayIndexOutOfBoundsException(){
#cold_bold		byte[] bytes = "hello".getBytes();
#cold_bold		//会引发数组下标越界异常
#cold_bold		System.out.println(bytes[bytes.length]);
#cold_bold	}
}

运行testArrayIndexOutOfBoundsException方法,在JUnit视图下会显示数组下标越界异常,如图-4所示。

图- 4

步骤四:制造强制类型转换异常

当出现异常的运算条件时,抛出此异常。例如,一个整数“除以零”时,抛出此异常。在此,首先创建测试方法testArithmeticException;然后,输出“5除以0”即会发生数学异常,代码如下所示:

import org.junit.Test;
/**
 * 测试常见的运行时异常
 */
public class TestRuntimeException {
	/**
	 * 测试空指针异常
	 */
	@Test
	public void testNullPointerException(){
		//...(代码略)
	}
	/**
	 * 测试数组下标越界异常
	 */
	@Test
	public void testArrayIndexOutOfBoundsException(){
		//...(代码略)
	}
#cold_bold	/**
#cold_bold	 * 测试数学异常
#cold_bold	 */
#cold_bold	@Test
#cold_bold	public void testArithmeticException(){
#cold_bold		//会引发数学异常
#cold_bold		System.out.println(5/0);
#cold_bold	}
}

运行testArithmeticException方法,在JUnit视图下会显示抛出了数学异常,如图-5所示。

图- 5

步骤五:制造强制类型转换异常

当试图将对象强制转换为不是实例的子类时,抛出该异常。在此,首先创建测试方法testClassCastException;然后,创建一个Object类的引用obj,赋值为字符串“hello”;最后将对象obj强制转换为Integer类的对象即会发生强制类型转换异常,代码如下所示:

import org.junit.Test;
/**
 * 测试常见的运行时异常
 */
public class TestRuntimeException {
	/**
	 * 测试空指针异常
	 */
	@Test
	public void testNullPointerException(){
		//...(代码略)
	}
	/**
	 * 测试数组下标越界异常
	 */
	@Test
	public void testArrayIndexOutOfBoundsException(){
		//...(代码略)
	}
	/**
	 * 测试数学异常
	 */
	@Test
	public void testArithmeticException(){
		//...(代码略)
	}
#cold_bold	/**
#cold_bold	 * 测试强制类型转换异常
#cold_bold	 */
#cold_bold	@Test
#cold_bold	public void testClassCastException(){
#cold_bold		Object obj = "hello";
#cold_bold		//会引发强制类型转换异常
#cold_bold		Integer i = (Integer)obj;
#cold_bold	}
}

运行testClassCastException方法,在JUnit视图下会显示抛出了类型转换异常,如图-6所示。

图-6

步骤六:制造NumberFormat异常

当应用程序试图将字符串转换成一种数值类型,但该字符串不能转换为适当格式时,抛出该异常。在此,首先创建测试方法testNumberFormatException;然后,使用Integer类的parseInt方法将字符串“a”转换为数值即会发生NumberFormat异常,代码如下所示:

import org.junit.Test;
/**
 * 测试常见的运行时异常
 */
public class TestRuntimeException {
	/**
	 * 测试空指针异常
	 */
	@Test
	public void testNullPointerException(){
		//...(代码略)
	}
	/**
	 * 测试数组下标越界异常
	 */
	@Test
	public void testArrayIndexOutOfBoundsException(){
		//...(代码略)
	}
	/**
	 * 测试数学异常
	 */
	@Test
	public void testArithmeticException(){
		//...(代码略)
	}
	/**
	 * 测试强制类型转换异常
	 */
	@Test
	public void testClassCastException(){
		//...(代码略)
	}
#cold_bold	/**
#cold_bold	 * 测试NumberFormat异常
#cold_bold	 */
#cold_bold	@Test
#cold_bold	public void testNumberFormatException(){
#cold_bold		//会引发NumberFormat异常
#cold_bold		int num = Integer.parseInt("a");
#cold_bold	}
}

运行testNumberFormatException方法,在JUnit视图下会显示抛出了NumberFormat异常,如图-7所示。

图-7

4.3 完整代码

本案例中,类TestRuntimeException的完整代码如下所示:

import org.junit.Test;

/**
 * 测试常见的运行时异常
 */
public class TestRuntimeException {
	/**
	 * 测试空指针异常
	 */
	@Test
	public void testNullPointerException(){
		String str = null;
		//会引发空指针异常
		System.out.println(str.length());
	}
	/**
	 * 测试数组下标越界异常
	 */
	@Test
	public void testArrayIndexOutOfBoundsException(){
		byte[] bytes = "".getBytes();
		//会引发数组下标越界异常
		System.out.println(bytes[bytes.length]);
	}
	/**
	 * 测试数学异常
	 */
	@Test
	public void testArithmeticException(){
		//会引发数学异常
		System.out.println(5/0);
	}
	/**
	 * 测试强制类型转换异常
	 */
	@Test
	public void testClassCastException(){
		Object obj = "hello";
		//会引发强制类型转换异常
		Integer i = (Integer)obj;
	}
	/**
	 * 测试NumberFormat异常
	 */
	@Test
	public void testNumberFormatException(){
		//会引发NumberFormat异常
		int num = Integer.parseInt("a");
	}
}

5 FileUtils实现文件复制功能(抛出自定义的文件复制异常)

5.1 问题

在上一案例的基础上,在工具类 FileUtils中再次定义文件复制方法,实现文件复制功能,并添加自定义异常处理。

5.2 方案

实现和使用自定义异常的过程如下:

1)首先,新建自定义异常类CopyException,该类继承自Exception;然后在该类中添加以下四个构造方法,这四个构造方法的实现,都为使用super调用父类对应参数的构造方法即可。以下是自定义异常一般的实现方式,代码如下:

public class CopyException extends Exception{
	public CopyException() {
		super();
	}
	public CopyException(String message, Throwable cause) {
		super(message, cause);
	}
	public CopyException(String message) {
		super(message);
	}
	public CopyException(Throwable cause) {
		super(cause);
	}
}

2)为了屏蔽底层的IOException,在实现文件复制的异常处理时,抛出自定义异常CopyException,即在catch块内使用throw关键字抛出自定义异常CopyException的实例,代码如下:

try {
			//实现文件复制
		} catch (FileNotFoundException e) {
			//抛出自定义异常
			throw new CopyException("文件没有找到",e);
		} catch (IOException e) {
			//抛出自定义异常
			throw new CopyException("读写异常",e);
		}

3)在实现复制的方法声明处使用throws关键字声明该方法会抛出自定义异常CopyException,代码如下:

public void testCopy1()throws CopyException{... ...}

5.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:新建自定义异常CopyException

首先,新建自定义异常类CopyException,该类继承自Exception;然后在该类中添加以下四个构造方法,这四个构造方法的实现都为使用super调用父类对应参数的构造方法,代码如下所示:

/**
 * 自定义异常
 */
public class CopyException extends Exception{
	public CopyException() {
		super();
	}
	public CopyException(String message, Throwable cause) {
		super(message, cause);
	}
	public CopyException(String message) {
		super(message);
	}
	public CopyException(Throwable cause) {
		super(cause);
	}
}

步骤二:添加测试方法

在类FileUtils中添加测试方法testCopy1,在该方法中实现文件复制功能,代码如下所示:

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import org.junit.Test;

public class FileUtils {
	/**
	 * 对复制文件的代码添加异常捕获机制
	 */
#cold_bold	@Test
#cold_bold	public void testCopy1()throws CopyException{
#cold_bold		FileInputStream fis = null;
#cold_bold		FileOutputStream fos = null;
#cold_bold		fis = new FileInputStream("fos.dat");
#cold_bold		fos = new FileOutputStream("fos_copy4.dat");
#cold_bold		int d = -1;
#cold_bold		while ((d = fis.read()) != -1) {
#cold_bold			fos.write(d);
#cold_bold		}
#cold_bold		System.out.println("复制完毕");
#cold_bold	}
}

步骤三:捕获并处理异常

为上一步骤中的代码添加自定义异常处理。首先,在catch块内使用throw关键字抛出自定义异常CopyException的实例,然后,在testCopy1方法声明处使用throws关键字声明该方法会抛出自定义异常CopyException,代码如下所示:

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import org.junit.Test;

public class FileUtils {
	/**
	 * 对复制文件的代码添加异常捕获机制
	 */
	@Test
#cold_bold	public void testCopy1()throws CopyException{
		FileInputStream fis = null;
		FileOutputStream fos = null;
#cold_bold		try {
			fis = new FileInputStream("fos.dat");
			fos = new FileOutputStream("fos_copy4.dat");
			int d = -1;
			while ((d = fis.read()) != -1) {
				fos.write(d);
			}
			System.out.println("复制完毕");
#cold_bold		} catch (FileNotFoundException e) {
#cold_bold			//抛出自定义异常
#cold_bold			throw new CopyException("文件没有找到",e);
#cold_bold		} catch (IOException e) {
#cold_bold			//抛出自定义异常
#cold_bold			throw new CopyException("读写异常",e);
#cold_bold		} 
	}
}

步骤四:资源清理

使用 finally块释放相关资源,及时将流fis、fos关闭,代码如下所示:

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import org.junit.Test;

public class FileUtils {
	/**
	 * 对复制文件的代码添加异常捕获机制
	 */
	@Test
	public void testCopy1()throws CopyException{
		FileInputStream fis = null;
		FileOutputStream fos = null;
		try {
			fis = new FileInputStream("fos.dat");
			fos = new FileOutputStream("fos_copy4.dat");
			int d = -1;
			while ((d = fis.read()) != -1) {
				fos.write(d);
			}
			System.out.println("复制完毕");
		} catch (FileNotFoundException e) {
			//抛出自定义异常
			throw new CopyException("文件没有找到",e);
		} catch (IOException e) {
			//抛出自定义异常
			throw new CopyException("读写异常",e);
#cold_bold		} finally {
#cold_bold			if (fis != null) {
#cold_bold				try {
#cold_bold					fis.close();
#cold_bold				} catch (IOException e) {
#cold_bold					e.printStackTrace();
#cold_bold				}
#cold_bold			}
#cold_bold			if (fos != null) {
#cold_bold				try {
#cold_bold					fos.close();
#cold_bold				} catch (IOException e) {
#cold_bold					e.printStackTrace();
#cold_bold				}
#cold_bold			}
#cold_bold		}
	}
}

步骤五:测试

运行testCopy1方法,如果当前工程目录下没有文件fos.dat,则将抛出CopyException异常,如图-8所示。

图-8

5.4 完整代码

本案例中,类CopyException的完整代码如下所示:

/**
 * 自定义异常
 */
public class CopyException extends Exception{
	public CopyException() {
		super();
	}
	public CopyException(String message, Throwable cause) {
		super(message, cause);
	}
	public CopyException(String message) {
		super(message);
	}
	public CopyException(Throwable cause) {
		super(cause);
	}
}

类FileUtils的完整代码如下所示:

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import org.junit.Test;

public class FileUtils {
//...(之前案例的代码,略)

	/**
	 * 对复制文件的代码添加异常捕获机制
	 */
	@Test
	public void testCopy1()throws CopyException{
		FileInputStream fis = null;
		FileOutputStream fos = null;
		try {
			fis = new FileInputStream("fos.dat");
			fos = new FileOutputStream("fos_copy4.dat");
			int d = -1;
			while ((d = fis.read()) != -1) {
				fos.write(d);
			}
			System.out.println("复制完毕");
		} catch (FileNotFoundException e) {
			//抛出自定义异常
			throw new CopyException("文件没有找到",e);
		} catch (IOException e) {
			//抛出自定义异常
			throw new CopyException("读写异常",e);
		} finally {
			if (fis != null) {
				try {
					fis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (fos != null) {
				try {
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}