Java的IO流和异常处理-v.ppt_第1页
Java的IO流和异常处理-v.ppt_第2页
Java的IO流和异常处理-v.ppt_第3页
Java的IO流和异常处理-v.ppt_第4页
Java的IO流和异常处理-v.ppt_第5页
已阅读5页,还剩66页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

2019/11/19,4.1I/O流概述4.2SystemI/O类和Scanner类4.2.1SystemI/O类4.2.2Scanner类4.3文件类4.3.1使用File类访问文件系统4.3.2随机文件读写4.4字节级输入输出流4.4.1数据输入输出流4.4.2文件输入输出流4.4.3缓冲输入输出流4.4.4管道输入输出流4.4.5格式化输出流,4.5字符级输入输出类4.5.1字符输入输出类4.5.2缓冲读写类4.5.3文件读写类4.5.4格式化写类4.6对象序列化4.6.1对象输入流4.6.2对象输出流4.7异常处理4.7.1Java中定义的异常4.7.2异常类的层次结构4.7.3捕获异常4.7.4异常处理的嵌套4.7.5自定义的异常和使用,第4章Java的I/O流和异常处理,2019/11/19,第4章Java的I/O流和异常处理,学习导读Java中常用I/O流、方法及其应用,包括:System类、Scanner类,字节流和字符流处理,以及对象序列化。Java中的异常处理机制及异常处理。,2019/11/19,4.1I/O流的概念,流是指流动的数据序列,可分为输入流和输出流。在程序设计语言中,流式输入输出是一种常见的输入输出方式。它是一个比文件更加广泛的概念。输入流将外部数据输入到计算机。例如从键盘,扫描仪,摄像头,网络等数据源输入数据。输出流将计算机中的数据输出到外部设备。例如将要打印的信息发送到打印机,将计算的结果显示到输出设备上。流的特点:所有数据的传输都按照数据序列的顺序进行。每个数据依序被读入或写出,Java中采用类的方式实现I/O流。,2019/11/19,JavaI/O流来自java.io包中的类,按照流处理的对象,可将输入输出流分为字节级输入输出流、字符级输入输出流和对象级输入输出流。输入输出流类层次如图所示:,2019/11/19,InputStream和OutputStream是Java语言中最基本的两个输入输出类。其他所有字节输入输出流类都继承自这两个基类。这两个类都是抽象类,都继承自Object类,因而不能创建它们的实例,只能使用它们的子类。,2019/11/19,从输入流读取下一个字节,-1表示输入结束,阻塞方法abstractintread();从输入流读取一组数据存入缓冲区b中。返回读取的字节个数,-1表示结束intread(byteb);从输入流读取最多len字节数据存入缓冲区b中,并从数组b的第off个位置开始存放intread(byteb,intoff,intlen);返回输入流中无需阻塞可直接读取字节个数intavailable();从输入流中忽略n和字节的数据,返回实际忽略的字节个数longskip(longn);关闭输入流close();,InputStream的主要方法,2019/11/19,向输出流写入一个字节,写出字节为整数b的低字节,其高3个字节被忽略abstractvoidwrite(intb);把缓冲区b中的全部数据写入输出流voidwrite(byteb);把缓冲区b中从boff开始的len个字节的数据写入输出流voidwrite(byteb,intoff,intlen);刷新输出流,强制输出所有被缓存的字节voidflush();关闭输出流voidclose();在实际应用中,常用InputStream和OutputStream类的引用指向它们的具体实现的子类对象。,OutputStream的方法,2019/11/19,4.2SystemI/O类和Scanner类SystemI/O类称为标准输入输出类。在Java中标准的输入设备是键盘,标准的输出设备是终端或显示器。他们分别对应System类中的变量in,out和err。这三个类变量(对象类型)在System类中的声明如下:publicstaticfinalInputStreamin;publicstaticfinalPrintStreamout;publicstaticfinalPrintStreamerr;,2019/11/19,4.2SystemI/O类和Scanner类对于PrintStream类最常用的两个方法为:publicvoidprint();/输出一行字符串publicvoidprintln();/输出后并换行例如,输入后立即输出这个数:bytebs=System.in.read();System.out.println(bs);,2019/11/19,Scanner类Scanner类是一个可以使用正则表达式来分析基本类型和字符串的简单文本扫描器。它使用分隔符模式将其输入分解为标记,默认情况下该分隔符模式与空白字符匹配。再使用不同的next方法将得到的标记转换为不同类型的值。例如,读入一个整数:Scannersc=newScanner(System.in);inti=sc.nextInt();,【例4.1】SystemI/O类和Scanner类,2019/11/19,注意,输入流的结束程序运行结果?,2019/11/19,4.3文件类,1.使用File类Java提供了用于处理有关文件和目录访问的File类。用户通过该类可以实现新建文件、删除文件或目录,以及获取文件或目录属性的功能。File类方法如表所示:,2019/11/19,例如,利用File对象创建文件和目录,注意,new操作一定成功吗?程序运行结果?,2019/11/19,2.使用RandomAccessFile类Java提供了RandomAccessFile类,它的实例能同时支持随机存取文件的读写操作,每读取一个字节,指针后移一个字节;写操作也在指针位置写字节,然后指针后移到所写字节之后。RandomAccessFile类有两个构造方法:RandomAccessFile(Stringfilename,Stringmode);RandomAccessFile(Filefile,Stringmode);其中,mode值可以是:,2019/11/19,RandomAccessFile类的方法,【例4.2】RandomAccessFile类,2019/11/19,注意,写入了基本类型数据程序运行结果?,2019/11/19,4.4字节级输入输出流,1.数据输入输出流(DataInputStream,DataOutputStream)数据输入流,是从一个输入流中读取Java基本类型的数据。数据输出流,向一个输出流写入Java基本类型的数据。它们允许程序以与机器无关的方式读取Java基本类型数据,这些类型在文件中的表示方式与其在内存中的一样,无需转换。其构造方法和一般方法分别是:,2019/11/19,2.文件输入输出流(FileInputStream,FileOutputStream)FileInputStream类和类FileOutputStream类分别继承于InputStream类和OutputStream类。这两个类可以打开本地主机上的文件,并进行顺序的读/写。它们的构造方式是:通常与其他字节输入输出类结合使用。,【例4.3】DataInputStream/DataOutputStream类,通过类File对象或者一个表示文件名的字符串可以生成文件输入/输出流对象,同时文件被打开,然后进行文件读/写。,2019/11/19,数据输入输出流与文件输入输出流结合举例,注意,写入了基本类型数据程序运行结果?,2019/11/19,3.缓冲输入输出流(BufferedInputStream,BufferedOutputStream)当创建一个BufferedInputStream类的实例时,也就创建了一个内部缓冲数组,缺省使用32字节大小的缓冲区.当读取数据时,数据按块读入缓冲区,其后的读操作则直接访问缓冲区。当写入数据时,首先写入缓冲区,当缓冲区满时,其中的数据写入所连接的输出流。使用方法flush()可以强制将缓冲区的内容全部写入输出流。,【例4.4】BufferedInputStream/BufferedOutputStream类,2019/11/19,程序功能?,2019/11/19,4.管道输入输出流(PipedInputStream,PipedOutputStream)这两个流用于进程之间的通信。一个PipedInputStream必须连接一个PipedOutputStream,反之亦然。下面是这两个对象建立联系的方法:,2019/11/19,管道用来把一个程序、线程或代码块的输出连接到另一个程序、线程或代码块的输入。管道输入流作为一个通信管道的接收端,管道输出流作为发送端。在使用管道之前,管道输出流和管道输入流必须进行连接。,2019/11/19,5.格式化输出流(PrintStream)PrintStream具有在System文件句柄使用过的System.out所有的格式化性能。PrintStream有以下两个构造方法:PrintStream(OutputStreamoutputStream)PrintStream(OutputStreamoutputStream,booleanflushOnNewline)注意,在上述这些字节输入输出流中,所读出的数据应该是由相应的写入类写入的。,2019/11/19,面向字节级I/O编程的一般步骤(1)磁盘文件或字节数据作为FileInputStream的构造方法的参数,实例化一个FileInputStream对象。(2)FileInputStream对象作为DataInputStream的构造方法的参数。(3)然后就可以使用InputStream类中的方法,进行字节输入流的操作。例如,read()方法及其重载方法,available(),skip(),close()等。或者用FileInputStream对象作为BufferedInputStream的构造方法的参数,然后使用read()等方法进行读操作。对于字节级输出流也具有相对应的类和方法。,2019/11/19,在Java中,定义了专门用于处理字符数据输入输出的抽象类Reader和Writer类,它们与InputStream和Output-Stream类很相似,也有很多子类。1.Reader类和Writer类它们是所有字符流的超类,它们是直接继承Object类的抽象类,可读写16位的字符流。类层次结构如图:,4.5字符输入输出类,2019/11/19,字节流不能直接操作Unicode字符。在Unicode字符中,一个汉字被看成一个字符。字符流与字节流的区别在于其处理数据的方式。字节流按字节来处理数据,而文本数据可能采用各种不同的字符编码方式,可能是单字节字符,也可能是多字节字符。因而要借助于字符流来处理文本类信息。,2019/11/19,BufferedReader从字符输入流中读取文本,该输入流的指向必须是一个Reader流(底层流),由该底层流将数据读入缓冲区,以后BufferReader类创建的流对象就从缓冲区中读取数据。其构造方法如下:publicBufferedReader(Readerin);,2.缓冲读写类(BufferedReader,BufferedWriter),2019/11/19,BufferedWriter类用来创建一个字符输出流。BufferWriter流将数据写入缓冲区,由底层流(像FileWriter流)写到最终目的地。其构造方法如下:publicBufferedWriter(Writerout);问题,当创建这些对象时,其传入参数可以是什么类型?,2.缓冲读写类(BufferedReader,BufferedWriter),2019/11/19,3.文件读写类(FileReader,FileWriter),FileReader类用来读取字符数据,其构造方法是:publicFileReader(Stringfilename)throwsFileNotFoundExceptionpublicFileReader(Filefile)throwsFileNotFoundExceptionFileWriter类用来写入字符数据,其构造方法是:publicFileWriter(StringfileName)throwsIOExceptionpublicFileWriter(Filefile)throwsIOException,2019/11/19,3.文件读写类(FileReader,FileWriter),例如,FileReaderfr=newFileReader(“temp.txt”);BufferReaderbr=newBufferReader(fr);Strings=br.readLine();,【例4.5】BufferedReader/BufferedWriter类,实际文件FileReader类BufferedReader类,实际文件FileWriter类BufferedWriter类,2019/11/19,注意,写入了字符数据程序运行结果n呢?,2019/11/19,利用文件读写类实现文件拷贝,与之前利用缓冲输入输出流进行文件拷贝进行对照程序功能?,2019/11/19,利用BufferedReader类可以从字节型流(像System.in)中读出字符数据。Java提供了一个将字节流转换成字符流的类InputStreamReader。反之,OutputStreamWriter类。它们的构造方法是:publicInputStreamReader(InputStreamin);publicOutputStreamWriter(OutputStreamout);,2019/11/19,【例4.6】InputStreamReader类,利用BufferedReader类可以从字节型流(像System.in)中读出字符数据。例如,BufferedReaderbr=newBufferedReader(newInputStreamReader(System.in);因此,BufferedReader类的对象br具有从字节数据中读出字符数据的能力。,2019/11/19,例如,从键盘读入一行数字字符,注意,用到了封装器类的方法程序运行结果?,2019/11/19,流结束的判断,read()返回-1。readXXX()readInt()、readByte()、readLong()、readDouble()等;产生EOFException。readLine()返回null。,2019/11/19,面向字符级I/O编程的一般步骤(l)将字符文件作为参数分别构造FileReader和FileWriter对象。(2)以FileReader对象作为参数构造BufferedReader对象。(3)以FileWriter对象作为参数构造PrintWriter对象。(4)调用BufferedReader对象的readLine()方法读取字符数据或者按照分隔符读取某个记录的每个字段。(5)调用PrintWriter对象的println()方法写入字符数据或记录。对于字符级输出流也具有相应的类和方法。,2019/11/19,利用BufferedReader类可以从字节型流(像System.in)中读出字符数据。Java提供了一个将字节流转换成字符流的类InputStreamReader。反之,OutputStreamWriter类。它们的构造方法是:publicInputStreamReader(InputStreamin);publicOutputStreamWriter(OutputStreamout);,2019/11/19,利用BufferedReader类可以从字节型流(像System.in)中读出字符数据。例如,BufferedReaderbr=newBufferedReader(newInputStreamReader(System.in);因此,BufferedReader类的对象br具有从字节数据中读出字符数据的能力。,【例4.7】InputStreamReader类,2019/11/19,对象序列化(Serialization)将那些实现了Serializable接口的对象转换成一个字节序列,并且能够将这个字节序列完全恢复为原来的对象,实现了对象的持久性。序列化以后的对象可以在网络上传输,使得不同的计算机可以共享对象。只有实现了Serializable接口的类的对象才可以被串行化,即该对象就是序列化的对象。注意,Serializable接口中没有任何的方法,实现该接口的类不需要实现额外的方法。,4.6对象序列化,2019/11/19,ObjectInputStream类用于读出由ObjectOutputStream写入的对象,只有支持Serializable接口的对象才可以从这个流中读出。其构造方法如下:publicObjectInputStream(InputStreamin)throwsIOExceptionObjectOutputStream类用于将已实现Serializable接口的对象写入到输出流中。其构造方法如下:publicObjectOutputStream(OutputStreamout)throwsIOException使用readObject(),writeObject方法可读写一个对象。,对象输入输出流(ObjectInputStream,ObjectOutputStream),【例4.8】ObjectInputStream类和ObjectOutputStream类,2019/11/19,程序运行结果?,程序代码,2019/11/19,串行化的注意事项,串行化能保存的元素只能保存对象的非静态成员变量,不能保存任何成员方法和静态的成员变量,而且串行化保存的只是变量的值,对于变量的任何修饰符,都不能保存。使用对象流把一个对象写到文件时不仅保证该对象是序列化的,而且该对象的成员对象也必须是可序列化的。,2019/11/19,串行化的注意事项,缺省的串行化机制,对象串行化首先写入类和字段的信息,然后按照名称的升序写入其数值。如果想自己明确地控制这些数值的写入顺序和写入种类,必须定义自己的读取数据流的方式。在类的定义中重写writeObject()和readObject()方法。,2019/11/19,异常:在程序运行过程中发生的错误,这些错误在编译时无法发现。如数组下标越界,0作为除数等。Java中定义了很多异常类,每个异常类都代表了一种或者多种运行错误,包含了该运行错误的信息和处理错误的方法等内容。每个异常类都继承自Exception类,如图所示:,4.7异常处理,2019/11/19,Java异常类的层次结构和继承关系,Error,一般指与JVM或动态加载等相关的问题,如虚拟机错误,动态链接失败,系统崩溃等,这类错误一般被认为是无法恢复和不可捕捉的,将导致程序中断。,2019/11/19,两种处理异常的机制捕获异常当Java运行时系统得到一个异常对象时,它将会沿着方法的调用栈逐层回溯,寻找处理这一异常的代码。寻找的对象从生成异常对象的代码块开始,沿着方法的调用栈逐层回溯,直到找到一个方法能够处理这种类型的异常为止。运行时系统把当前异常对象交给这个方法进行处理,这一过程称为捕获(catch)异常。如果Java运行时系统找不到可以捕获异常的方法,则运行时系统将终止,相应的Java程序也将退出。,2019/11/19,两种处理异常的机制声明抛出异常如果一个方法并不知道如何处理所出现的异常,则可在方法声明时,声明抛出(throws)异常。这是一种消极的异常处理机制。,2019/11/19,在Java程序的执行过程中,若出现了异常事件,就会生成一个异常对象。异常对象可能是由正在运行的方法生成,也可能由Java虚拟机生成,其中包含一些信息指明异常事件的类型,及当异常发生时程序的运行状态等。其中,类RuntimeException代表运行时由JVM生成的异常,即在程序运行时发现的由Java解释器引发的各种异常。例如,ArithmeticException,ArrayIndexOutOfBoundsException等。其他的为非运行时异常,是指能由编译器在编译时检测是否发生在方法的执行过程中的异常,例如,IOException,FileNotFoundException等。,2019/11/19,java.lang,java.io和包中定义了很多异常类。Java编译器要求Java程序必须捕捉或声明抛出所有的非运行时异常。但对运行时异常可以不作处理。,2019/11/19,try-catch-finally语句块try/可能发生异常的语句或语句块catch(ExceptionType1name1)/对ExceptionType1类型异常进行处理catch(ExceptionType2name2)/对ExceptionType2类型异常进行处理finally/强制执行语句块,Java异常处理语句,2019/11/19,try-catch-finally语句块的执行流程(1)try块中的语句没有产生异常,在这种情况下,Java首先执行try块中的所有语句,然后执行finally子句中的代码,最后执行try-catch-finally语句块后面的语句。(2)try块中的语句产生了异常,且此异常在方法内被捕获。此时,Java先执行try块中的语句,直到产生异常,然后跳过此try中的后续语句,执行捕捉此异常的catch块中的语句,然后执行finally子句中的语句。注意:无论try块中是否出现异常,finally块中的语句总是得到执行。,2019/11/19,对多个异常进行处理时,程序会按照catch语句的排列顺序匹配被捕捉的异常和每个catch语句的参数,直到找到可以匹配的异常处理方法。多个catch语句的参数应该按照匹配范围由窄到宽的顺序排列。否则会引起以下编译错误:“catch”hasalreadybeencaught即,如果宽类型的catch块先于被执行到就会导致那些在后面出现的窄类型catch块永远得不到执行!,2019/11/19,异常的捕获及其处理1.可以在方法体中直接捕获可能出现的异常。在列出多个异常类时由窄类型到宽类型依序排列。例如,voidtestExceptiontry.catch(IOExceptione)catch(Exceptione),【例4.9】异常未捕获和直接捕获,2019/11/19,下面是未处理异常时的例子publicclasstestExceptionpublicstaticvoidmain(Stringargs)intx,y,result;x=5;y=0;result=x/y;System.out.println(“这是一个测试字符串!);该程序的运行结果是:,2019/11/19,下面是增加异常处理时的例子publicclasstestException2publicstaticvoidmain(Stringargs)intx=5,y=0,result;tryresult=x/y;System.out.println(“发生异常时不会被执行的语句!);catch(Exceptione)System.out.println(e.toString();System.out.println(“这是一个测试字符串!);该程序的运行结果是:,2019/11/19,下面是完整的异常处理的情形,该程序的运行结果是:,如果执行return语句呢?,2019/11/19,下面是捕捉多个catch块的情形,该程序的运行结果是:,2019/11/19,对多个异常进行处理时,程序会按照catch语句的排列顺序匹配被捕捉的异常和每个catch语句的参数,直到找到可以匹配的异常处理方法。多个catch语句的参数应该按照匹配范围由窄到宽的顺序排列。否则会引起以下编译错误:“catch”hasalreadybeencaught即,如果宽类型的catch块先于被执行到就会导致那些在后面出现的窄类型catch块永远得不到执行!,2019/11/19,2.方法声明抛出异常可以在方法的定义中利用throws关键字声明该方法抛出异常的类型。把那些在方法中不关心或不方便处理的异常传递给上层调用处理。通常,方法的调用者会去捕获这些异常。throws语法如下:voidmethodName()throwsExceptionType1,ExceptionTypen,运行时异常需要捕获吗?,【例4.10】声明异常和间接捕获,2019/11/19,程序运行结果?,2019/11/19,4.异常处理的嵌套,Java语言的try-catch语句可以嵌套,即在try块中可以包含另外的try-catch语句。其格式如下:tryt

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论