第5章 异常处理与输入输出.ppt
第第5章章 异常处理与输入输出异常处理与输入输出异常处理输入输出一、异常异常指的是程序运行过程中出现的非正常事件。其中非正常事件指的是被0除、用户输入出错、找不到文件等异常指的是运行错误,编译错误不是异常Java对异常的处理1.提供大量的异常类(1)Java预定义了很多Exception类和Error类及其大量的子类来描述异常。这些类都是Throwable类的子类。(2)Java的异常类分为 运行时异常类:继承RuntimeException的类 非运行时异常类:除RuntimeException类及其子类外 见教材p1312.异常处理方式(1)系统自动处理 一旦程序中出现异常,运行时系统将会自动产生一个相应的异常类对象,每一个异常事件都由一个异常对象来描述。public class ExceptionExample static int num;public static void main(String args)num=Integer.parseInt(args0);System.out.println(100整除+num+=+100/num);本程序若输入num值为0,则产生ArithmeticException异常类对象(2)程序员主动干预异常运用异常处理机制对可能出现的异常进行干预,干预手段两种:a.使用trycatchfinally结构对异常进行捕获和处理 b.通过throw或throws关键字将异常抛出。a.使用trycatchfinally结构对异常进行捕获和处理其语法格式:try/程序代码(可能导致异常的代码)catch(异常类类型1 对象名1)/程序代码 catch(异常类类型2 对象名2)/程序代码 finally/程序代码 说明请见教材p133例:利用trycatchfinally结构捕获ExceptionExample类中所有的异常public class ExceptionExample static int num;public static void main(String args)try num=Integer.parseInt(args0);System.out.println(100整除整除+num+=+100/num);catch(ArrayIndexOutOfBoundsException e)System.out.println(你还没有输入呢,请输入整数值你还没有输入呢,请输入整数值!);catch(NumberFormatException e)System.out.println(你输入的是小数或字符,请输入整数值你输入的是小数或字符,请输入整数值!);catch(ArithmeticException e)System.out.println(你输入的是你输入的是0,请输入非,请输入非0整数值整数值!);b.通过throw或throws关键字将异常抛出(a)利用throw关键字直接抛出异常在编写程序的过程中,对可能会引发异常的地方直接使用throw语句自行抛出,当直接利用throw语句抛出异常时,一定要对抛出的异常进行捕获。语法格式:throw new 异常类类型(信息)其中异常类类型为系统异常类名或用户自定义的异常类名。toString方法可返回上面的信息内容 例:直接抛出异常以处理分母输入为0的情况public class ExceptionDemo static int num;public static void main(String args)try num=Integer.parseInt(args0);if(num=0)throw new ArithmeticException(你应该输入非0整数值!);System.out.println(100整除+num+=+100/num);catch(ArrayIndexOutOfBoundsException e)System.out.println(你还没有输入呢,请输入整数值!);catch(NumberFormatException e)System.out.println(你输入的是小数或字符,请输入整数值!);catch(ArithmeticException e)System.out.println(错误类型:+e.toString();(b)利用throws关键字间接抛出异常在方法的声明处,利用throws关键字抛出异常。语法格式如下:方法名()throws 异常类异常类1,异常类2,例:ExceptionDemo类中的DivMethod方法计算100/num的值,并在该方法中抛出异常。MyDemo类调用DivMethod方法时,捕获其抛出的异常。class ExceptionDemo public static void DivMethod(int num)throws NumberFormatException,ArithmeticException,ArrayIndexOutOfBoundsException System.out.println(100整除+num+=+100/num);public class MyDemo public static void main(String args)try int n;n=Integer.parseInt(args0);ExceptionDemo.DivMethod(n);catch(ArrayIndexOutOfBoundsException e)System.out.println(你还没有输入呢,请输入整数值!);catch(NumberFormatException e)System.out.println(你输入的是小数或字符,请输入整数值!);catch(ArithmeticException e)System.out.println(你输入的是0,请输入非0整数值!);三、自定义异常语法结构:语法结构:class 自定义异常类名自定义异常类名 extends Exception(Throwable)public 自定义异常类名自定义异常类名()public 自定义异常类名自定义异常类名(String str)super(str);用throw语句来抛出自定义的异常类,例:要求在命令行后输入学生成绩,成绩值在0,100之间。当输入的数值不在0,100之间时,直接抛出自定义的异常类InputException类。同时要求捕获所有可能出现的异常。自定义的异常:class InputException extends Exception public InputException()public InputException(String str)super(str);public class Scores public static void main(String args)try float score;System.out.println(请输入成绩值!)score=Math.abs(Float.parseFloat(args0);if(score=100)throw new InputException();System.out.println(你输入的成绩值:+score);catch(ArrayIndexOutOfBoundsException e)System.out.println(你还没有输入呢,请输入成绩值!);catch(NumberFormatException e)System.out.println(你输入的是字符,请输入数值!);catch(InputException e)System.out.println(你输入的数值不在指定范围内,请输入0,100之间的值!);输入输出数据的输入输出是程序的主要任务。进行程序设计时,有时需将结果保存到指定的文件、数据库中等等。Java语言的输入输出数据是以流(Stream)的形式出现的。流分为输入流(Input Stream)和输出流(Output Stream)输入流和输出流的流向 1 1.Java I/OJava I/O系统系统 Java程序的输入和输出是由Java I/O系统负责处理的I/O类库位于java.io包中 2.几个重要的居于几个重要的居于java.io包中类层次顶部的流类包中类层次顶部的流类 类 说明 File 支持文件与目录操作的类 InputStream 字节输入流类 OutputStream 字节输出流类 Reader 字符输入流类 Writer 字符输出流类 RandomAccessFile 随机访问文件类3.文件管理类(File)Java中的File类是专门对目录和文件进行管理的类对目录的管理包括建立目录、删除目录、重命名目录以及建立与删除临时目录;对文件的管理包括建立空文件、删除文件、重命名文件、获取或修改文件的各种属性以及建立与删除临时文件。Java中的File类是不能读写文件的。File类的构造方法 File(String pathname)该构造方法中的参数pathname,指定所创建的File类对象对应的目录或文件 File myfile=new File(:jdkmyjava);File myfile=new File(“c:jdkmyjavaMyJava.class);创建的对象myfile表示:jdkmyjava目录中的文件MyJava.class。(2)File(File parent,String child);该构造方法用一个已经创建的对应于某个目录的File类对象,作为路径参数来创建File类对象,如:File MyFile=new File(:jdkmyjava);File MyFile1=new File(MyFile,MyJava.java);File类的成员方法(p142表5-2)public String getName()返回目录或文件名public String getPath()返回目录或文件所在路径public String getAbsolutePath()以字符串形式返回目录或文件的绝对路径public String getParent()以字符串形式返回目录或文件的父目录例例:请显示c盘中的所有内容import java.io.*;class ListFileName public static void main(Stringargs)Stringallname;File myfile1=new File(c:);if(myfile1.isDirectory()allname=myfile1.list();if(allname.length=0)System.out.println(“该目录下没有任何内容!);else System.out.println(“该目录下的内容有:);for(int i=0;iallname.length;i+)System.out.println(allnamei);else System.out.println(不存在该目录);例:例:创建文件和目录import java.io.*;class CMFileObject public static void main(Stringargs)try File myfile1=new File(c:myjdk);File myfile2=new File(myfile1,YouJava.java);System.out.println(两个对象创建完毕!);if(myfile1.exists()System.out.println(myfile1+存在!);else myfile1.mkdir();System.out.println(myfile1+已创建!);if(myfile2.exists()System.out.println(myfile2+存在!);else System.out.println(myfile2+文件不存在,请创建!);myfile2.createNewFile();System.out.println(myfile2+文件已创建!);catch(IOException e)例例显示文件的一些属性import java.io.*;import java.util.Date;class ShowFileAttri public static void main(Stringargs)File f=new File(“myfile.txt”)if(f.exists()System.out.println(文件tt属性);System.out.println(名称:tt+f.getName();System.out.println(可读性:tt+f.canRead();System.out.println(可写性:tt+f.canWrite();System.out.println(隐藏性:tt+f.isHidden();System.out.println(长度:tt+f.length();Date date=new Date(f.lastModified();System.out.println(最后修改日期:t+date.toString();elseSystem.out.println(f.getName()+“不存在!”);练习(P179):设计一个文件管理器。要求从命令行输入文件的路径(第一个参数)和文件名(第二个参数),从而实现显示文件、删除文件等基本操作。要求捕获所有的异常。4、Java中对文件进行读写的类 字节流类字符流类文件随机读取类(RandomAccessFile)(1)字节流字节流是指数据流中最小的数据单元是字节,它为处理字节的输入和输出提供了方便,如使用字节流读取或输出二进制数据 字节流分为字节输入流和字节输出流 在I/O类库中,它们分别由InputStream和OutputStream表示InputStream、OutputStream都是抽象类,不能被实例化,该类中所有的方法在出错条件下都会引发IOException异常 InputStream和OutputStream类的读写是面向字节的,其实现读/写的操作方法是read()/write()方法 还有其它的方法参见教材p147149字节输入流字节输入流InputStream部分子类继部分子类继承关系图承关系图 InputStream 基本字节输入流FileInputStream 基本文件输入流PipedInputStream 用作线程通信的管道输入流ByteArrayInputStream 字节数组输入流FilterInputStream 在基本输入流中增加新功能的抽象输入流BufferedInputStream 基本缓冲区输入流DataInputStream 读取原始数据类型的输入流利用FileInputStream实现字节流文件的顺序读取类的构造方法如下FileInputStream(String name)throws FileNotFoundException该方法中name为本地文件名,若希望程序可以从文件读取字节数据,必须创建一个FileInputStream对象与要读取的文件建立联系。例:将ByteFileRead.java文件内容输出到屏幕上 import java.io.*;public class ByteFileRead public static void main(String args)throws IOException FileInputStream f1=new FileInputStream(ByteFileRead.java);int data=f1.read();while(data!=-1)System.out.print(char)data);data=f1.read();f1.close();FileInputStream(File file)throws FileNotFoundException该方法中file是文件对象,可以使用文件对象指定文件,再创建一个FileInputStream对象间接的与文件对象所指定的文件建立联系。如,可以使用文件对象指定ByteFileRead.java文件,再与文件输入流建立联系:File f=new File(ByteFileRead.java);FileInputStream f1=new FileInputStream(f);然后调用不同形式的read()方法顺序读取文件ByteFileRead.java的内容 字节输出流字节输出流OutputStream部分子类部分子类继承关系图继承关系图利用FileOutputStream实现字节流文件的顺序写入该类的构造方法如下 FileOutputStream(String name)throws FileNotFoundException该方法中name为本地文件名,若希望程序可以将数据写入文件,必须创建一个FileOutputStream对象与要写入的文件建立联系。然后调用不同形式的write()方法向指定的文件写入数据。FileOutputStream(String name,boolean append)throws FileNotFoundException该方法中append的值为false时,以覆盖的方式向文件写入数据,否则,以追加的方式向文件写入数据。其它的同。FileOutputStream(File file)throws FileNotFoundException该方法中file是文件对象,可以使用文件对象指定文件,再创建一个FileOutputStream对象间接地与文件对象所指定的文件建立联系。如,可以使用文件对象指定ByteFileWrite.txt文件,再与文件输出流建立联系:File f=new File(ByteFileWrite.txt);FileOutputStream f2=new FileOutputStream(f);然后调用不同形式的write()方法向文件ByteFileWrite.txt写入数据。FileOutputStream(File file,boolean append)throws FileNotFoundException该方法中append的值为false时,以覆盖的方式向文件写入数据,否则,以追加的方式向文件写入数据。其它的同。例:要求从键盘输入一串字符串到指定的文件中import java.io.*;public class ByteFileWrite public static void main(String args)throws IOException byte inChar=new byte30;System.out.println(请输入一串字符串:);System.in.read(inChar,0,30);FileOutputStream fos=new FileOutputStream(myfile.txt,true);fos.write(inChar);fos.close();System.out.println(写文件完毕!rn可在本程序同一目录下查看到myfile.txt文件!);练习:请将ByteFileRead.java文件内容拷贝到文件myfile.txt文件中。(2)字符流字符流是指数据流中最小的数据单元是字符。字符流分为字符输入流和字符输出流,在I/O类库中,它们分别由Reader和Writer表示。Reader、Writer都是抽象类,不能被实例化,该类中所有的方法在出错条件下都会引发IOException异常。Reader和Writer类的读写是面向字符的,其实现读/写的操作方法也是read()/write()方法。字符输入流字符输入流Reader部分子类继承关系部分子类继承关系图图Reader 基本字符输入流InputStreamReader 转换InputStream为Reader,可以指定数据源的字符编码FileReader InputStreamReader类的子类,是用于从文件中读入字符流的类BufferedReader 具有缓冲功能的字符输入类LineNumberReader 为其它Reader提供读缓冲区,同时可以跟踪字符输入流中的行号FilterReader 扩展其它Reader的功能字符输入流字符输入流Writer部分子类继承关系部分子类继承关系图图Writer基本字符输出流OutputStreamWriter转换OutputStream为Writer,可以指定数据汇的字符编码FileWriter OutputStreamWriter类的子类,是用于向文件中写入字符流的类BufferedWriter 具有缓冲功能的字符输出类 FilterWriter 扩展其它Writer的功能。PrintWriter 输出格式化数据利用文件字符流读取文件内容例:将例:将ByteFileRead.java文件内容拷贝到CopyCharacterFileRead.txt新文件中import java.io.*;public class CharacterFileRead public static void main(String args)throws IOException try FileReader f1=new FileReader(ByteFileRead.java);FileWriter f2=new FileWriter(CopyCharacterFileRead.doc);int data=f1.read();while(data!=-1)f2.write(data);data=f1.read();f1.close();f2.close();System.out.println(你已成功将ByteFileRead.java文件内容拷贝到CopyCharacterFileRead.txt文件中,rn可在本程序同一目录下查到!);catch(FileNotFoundException e)System.out.println(文件ByteFileRead.java不存在!);字符输入缓冲流BufferedReader BufferedReader类是Reader类的子类是一个字符输入缓冲流类,可以利用缓冲技术更高效的从字符输入流中读取字符数据。当程序需要从一个文件中读取数据时,我们可以通过FileReader类创建的流读取字符数据,但读取的效率不高,一次可以读取一个或多个字符,如前面的例子所示。使用基于缓冲的BufferedReader类创建的流读取数据时,可以利用该类提供的String readLine()方法一次读取一行字符。构造方法 BufferedReader(Reader inputStream)该方法创建一个默认输入缓冲区大小的输入缓冲字符流。字符输出缓冲流BufferedWriter BufferedWriter类是Writer类的子类是一个字符输出缓冲流类,可以利用缓冲技术更高效的向一个字符输出流中写入字符数据。该类提供了newLine()方法,每次调用向输出流写入换行符,与BufferedReader的readLine()方法相匹配。BufferedWriter类的构造方法如下:BufferedWriter(Writer outputStream)该方法创建一个默认输出缓冲区大小的输出缓冲字符流。例:例:字符缓冲流的应用(将ByteFileRead.java文件拷贝到CopyByteFileRead.doc文件中)import java.io.*;public class IOBufferedStream public static void main(String args)throws IOException try BufferedReader br=new BufferedReader(new FileReader(ByteFileRead.java);BufferedWriter bw=new BufferedWriter(new FileWriter(CopyByteFileRead.doc);String line=br.readLine();while(line!=null)bw.write(line);bw.newLine();System.out.println(line);line=br.readLine();bw.close();br.close();System.out.println(你已成功将ByteFileRead.java文件内容拷贝到CopyCharacterFileRead.txt文件中,rn可在本程序同一目录下查到!);catch(FileNotFoundException e)System.out.println(ByteFileRead.java文件不存在!);(3)文件随机读取类(RandomAccessFile)在实际的编程中,有时只需要访问文件的部分内容,并且可以在随意的位置读取和写入数据。Java提供了RandomAccessFile类来实现对文件的随机访问。通过创建RandomAccessFile类的流对象,来实现对文件的随机访问。RandomAccessFile的父类是Object类。它既是输入流又是输出流,既可以进行读操作,也可以进行写操作,也可以在文件的任意位置进行读写操作。RandomAccessFile实现的是文件的随机读写,它是通过移动指针来实现的,在RandomAccessFile类中提供了许多操作指针的方法。两个主要构造方法:p167对文件位置指针操作的一些常用的方法:p168对文件读操作的一些方法:p168对文件写操作的一些方法:p168包含的一些其它常用方法 例例5-17 随机读取文件实例import java.io.*;public class RandomFileExample public static void main(Stringargs)throws IOException long pos1,pos2;String str,temp;System.out.println(Begin copying RandomFileExample.java to craf_exp.txt!);RandomAccessFile rafr=new RandomAccessFile(RandomFileExample.java,r);RandomAccessFile rafw=new RandomAccessFile(craf_exp.txt,rw);while(rafr.getFilePointer()rafr.length()temp=rafr.readLine()+n;rafw.writeChars(temp);rafw.seek(0);str=rafw.readLine();System.out.println(str);rafw.seek(20);pos1=rafw.getFilePointer();rafw.seek(40);pos2=rafw.getFilePointer();for(long i=pos1;ipos2;i+)System.out.print(rafw.readChar();