第6章 I/O流与异常
一、简答题
1.简述Error和Exception的区别与联系。
【答】Error(错误)表示系统级的错误和程序不必处理的异常,是java运行环境中的内部错误或者硬件问题,比如,内存资源不足等。对于这种错误,程序基本无能为力,除了退出运行别无选择。Exception表示一种设计或实现问题,表示需要捕捉或者需要程序进行处理的异常。他处理的是因为程序的瑕疵而引起的问题,或者在外的输入等引起的一般性问题,是程序必须处理的;也就是说,他表示如果程序运行正常,从不会发生的情况。
2.简述异常处理的过程。
【答】有异常产生时,有两种方式处理异常:
(1) 抛出:
public voud f() throws Exception
(2) 使用try、catch和finally块处理异常:
try{
…
}catch(){
…
}finally{
…
}
异常分为检查时异常和非检查异常,调用需要抛出检查时异常的方法时必须捕获异常或者显示抛出异常,调用非检查异常抛出的方法时不用捕获或者显示抛出,但你也可这么做,非检查时异常是指继承RuntimeException或者Error的异常,除此之外继承Exception的异常叫做检查时异常
3.什么时运行时异常和非运行时异常,它们两者的区别是什么?
【答】所谓的运行时异常,可以这样理解:如果这种异常不捕获的话,程序还是能正常编译通过,只是在运行的时候,有可能会出现异常,导致程序无法正常运行,例如你说的那个例子就是运行时异常,当i=0的时候,它会报错,但是不等于0就可以正常通过。
所谓非运行时异常,又叫检查异常,这种异常是一定要捕获的,如果不捕获,程序无法正常编译。例如,你需要操作一个文件,在程序中你标记了文件的位置,但是在实际中,文件可能存在,也可能不存在,这时候需要捕获异常,处理当文件不存在的情况。
4.简述throw和throws的区别。
【答】throw用于方法体内,并且抛出(产生)一个异常类对象,而throws用在方法声明时用来指明方法可能抛出(不处理)的多个异常。
二、阅读程序题
1.阅读下列程序,描述程序的功能,如果文件“a.txt”中的内容为“Thank you!”,则程序的运行结果是什么?
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
public class TestJavaIO {
public static void main(String[] args) {
int b = 0;
long num = 0;
InputStream in = null;
try {
in = new FileInputStream("D:/a.txt");
} catch (FileNotFoundException e) {
System.out.println("文件找不到");
System.exit(-1);
}
try {
while ((b = in.read()) != -1) {
System.out.print((char) b);
num++;
}
in.close();
System.out.println();
System.out.println("共读取了" + num + "个字节");
} catch (IOException e) {
System.out.println("文件读取错误");
System.exit(-1);
}
}
}
【答】程序运行结果:
Thank you!
读取了10个字节
2.阅读下列程序,描述程序的功能,并写出程序的运行结果。
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class TestObjectStream {
public static void main(String[] args) {
T t = new T();
t.k = 10;
try {
FileOutputStream fos = new FileOutputStream("D:/testObjectIo.bak");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(t);
oos.flush();
oos.close();
FileInputStream fis = new FileInputStream("D:/testObjectIo.bak");
ObjectInputStream bis = new ObjectInputStream(fis);
T tReader = (T) bis.readObject();
System.out.println(tReader.i + " " + tReader.j + " " + tReader.d + " " + tReader.k);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
} catch (ClassNotFoundException e2) {
e2.printStackTrace();
}
}
}
class T implements Serializable {
int i = 2;
int j = 4;
double d = 2.5;
transient int k = 15;
}
【答】程序运行结果:
2 4 2.5 0
三、编程题
1.在D盘存在“Exercise6_1.txt”文件,文件的内容为“Hello World!”。创建一个File类的对象,然后创建文件字节流输入流对象fis,并且从输入流中读取文件“Hello.txt”的信息。
【答】
import java.io.*;
public class Exercise6_1 {
public static void main(String args[]) {
File f = new File("D:\\Exercise6_1.txt");
try {
byte bytes[] = new byte[512];
FileInputStream fis = new FileInputStream(f); //创建文件字节输入流
int rs = 0;
System.out.println("The content of Exercise6_1 is:");
while ((rs = fis.read(bytes, 0, 512)) > 0) {
//在循环中读取输入流的数据
String s = new String(bytes, 0, rs);
System.out.println(s);
}
fis.close(); //关闭输入流
} catch (IOException e) {
e.printStackTrace();
}
}
}
2.在D盘存在文件“Exercise6_2.txt”,文件的内容为“今天心情非常好!”。使用InputStreamReader读取文件“Exercise6_2.txt”的内容。
【答】
import java.io.*;
public class Exercise6_2 {
public static void main(String args[]) {
try {
int rs;
File file = new File("D:\\", "Exercise6_2.txt");
FileInputStream fis = new FileInputStream(file);
InputStreamReader isr = new InputStreamReader(fis);
System.out.println("The content of Exercise6_2 is:");
while ((rs = isr.read()) != -1) { // 顺序读取文件里的内容并赋值给整型变量b,直到文件结束为止。
System.out.print((char) rs);
}
isr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
3.在D盘创建文件“Exercise6_3.txt”,并且输入一些内容,用BufferedReader和BufferedWriter类实现从文件“Exercise6_3.txt”中读取数据,复制到文件文件“Exercise6_3back.txt”中,最终使两个文件内容相同。
【答】
import java.io.*;
public class Exercise6_3 {
public static void main(String args[]) {
try {
FileReader fr;
fr = new FileReader("D:\\Exercise6_3.txt");// 创建BufferedReader对象
File file = new File("D:\\Exercise6_3back.txt");
FileWriter fos = new FileWriter(file);// 创建文件输出流
BufferedReader br = new BufferedReader(fr);
BufferedWriter bw = new BufferedWriter(fos);// 创建BufferedWriter对象
String str = null;
while ((str = br.readLine()) != null) {
bw.write(str + "\n"); // 为读取的文本行添加回车
}
br.close();// 关闭输入流
bw.close();// 关闭输出流
} catch (IOException e) {
e.printStackTrace();
}
}
}
4.在D盘创建文件“Exercise6_4.txt”,应用对象序列化知识将用户对象的信息保存到此文件中,之后将对象读入修改密码后再写回文件。
(1) 创建user类,构造方法中存在姓名、密码、年龄3个参数,并实现Serializable接口。
(2) 创建Exercise6_4类,将user类的对象写入“Exercise6_4.txt”文件中,之后读入该对象并修改用户密码。
【答】
import java.io.*;
import java.io.Serializable;
class user implements Serializable {
String name;
String password;
int age;
user(String name, String password, int age) {
this.name = name;
this.password = password;
this.age = age;
}
public void setpassword(String pass) {
this.password = pass;
}
}
public class Exercise6_4 {
public static void main(String args[]) {
user use = new user("Tom", "111", 21);//创建user类的对象
try {
FileOutputStream fos = new FileOutputStream("D:\\Exercise6_4.txt");
//创建输出流的对象,使之可以将对象写入文件中
ObjectOutputStream obs = new ObjectOutputStream(fos);
obs.writeObject(use);//将对象写入文件中
System.out.println("未修改写入文件的用户信息");
System.out.println("用户名:" + use.name); //打印文件中的信息
System.out.println("原密码:" + use.password);
System.out.println("年龄:" + use.age);
FileInputStream fis = new FileInputStream("D:\\Exercise6_4.txt");
//创建输入流的对象,使之可以从文件中读取数据
ObjectInputStream ois = new ObjectInputStream(fis);
use = (user) ois.readObject();//读取文件中的信息
use.setpassword("1111");//修改密码
System.out.println("修改之后文件中的信息");
//打印修改后的文件信息
System.out.println("用户名:" + use.name);
System.out.println("修改后的密码:" + use.password);
System.out.println("年龄:" + use.age);
} catch (Exception e) {
e.printStackTrace();
}
}
}
5.在编写程序过程中,如果希望一个字符串的内容全部是英文字母,若其中包含其他的字符,则抛出一个异常。因为在Java内置的异常类中不存在描述该情况的异常,所以需要我们自定义该异常类。
(1) 创建MyException异常类,此部分要求读者自己编写。
【答】
class MyException extends Exception {//继承Exception类
private String content;
public MyException(String content) {//构造方法
this.content = content;
}
public String getContent() {//获取描述信息
return this.content;
}
}
(2) 创建Exercise6_5类,在此类中创建一个带有String型参数的方法check(),该方法用来检查参数中是否包含英文字母以外的字符。若包含,则通过throw抛出一个MyException异常对象给check()方法的调用者main()方法。此部分代码已给出,要求根据下面的代码写出自定义类MyException的代码。
public class Exercise6_5 {
public static void check(String str) throws MyException {//指明要抛出的异常
char a[] = str.toCharArray();//将字符串转换为字符数组
int i = a.length;
for (int k = 0; k < i - 1; k++) { //检查字符数组中的每个元素
//如果当前元素是英文字母以外的字符
if (!((a[k] >= 65 && a[k] <= 90) || (a[k] >= 97 && a[k] <= 122))) {
//抛出MyException异常类对象
throw new MyException("字符串\"" + str + "\"中含有非法字符!");
}
}
}
public static void main(String[] args) {
String str1 = "HellWorld";
String str2 = "Hell!MR!";
try {
check(str1);//调用check()方法
check(str2);//执行该行代码时,抛出异常
} catch (MyException e) {//捕获MyException异常
System.out.println(e.getContent());//输出异常描述信息
}
}
}
×
确定