第9章 输入输出流.ppt
第9章输入输出流n9.1数据流的概念n9.2基本输入输出类n9.3对象流n9.4文件的操作9.1数据流的概念n9.1.1输入流和输出流n9.1.2字节流和字符流n9.1.3Java的标准数据流9.1.1输入流和输出流n在Java中,把所有输入和输出都当作流来处理。n流流是按一定顺序排列的数据的集合n输入数据时,一个程序打开数据源上的一个流(文件或内存等),然后按顺序输入这个流中的数据,这样的流称为输入流输入流n输出数据时,一个程序可以打开一个目的地的流,然后按顺序从程序向这个目的地输出数据,这样的流称为输出流输出流n输入和输出的方向是以程序为基准的。通常,也把从输入流中输入数据到程序中称为读读数据(read),反之,从程序中将数据输出到输出流中称为写写数据(write)n具体步骤一般为:打开一个流while(数据存在时)读数据或写数据 关闭流 9.1.2字节流和字符流nJava的输入输出流中,根据它们的数据类型,主要可分为两类1.字符流n字符流的输入输出数据是字符码,即Unicode字符(当遇到不同编码的字符时,Java的字符流会自动将其转换成Unicode字符)n字符流有两个基本类:Reader类和Writer类nReader类和Writer类分别为字符型输入输出流提供了读写字符的基本方法。2.字节流n字节流是按字节读/写二进制数据n字节流有两个基本的类:InputStream类和OutputStream类。InputStream类和OutputStream类分别为字节型输入输出流提供了读写字节码的基本方法9.1.3Java的标准数据流njava.lang包的System类定义了三个成员变量,分别是:nlstaticfinalInputStreamin标准输入innlstaticfinalPrintStreamout标准输出outnlstaticfinalPrintStreamerr标准错误输出errn我们可以直接使用这些成员变量,不需要创建对象。in可以直接调用InputStream类提供的输入方法;out和err可以直接调用PrintStream类提供的输出方法nout用于屏幕输出,常用的调用方法有:lSystem.out.print(String str);向 屏幕输出字符串strnlSystem.out.println(Stringstr);向屏幕输出字符串str后换行nin用于屏幕输入,常用的调用方法有:nlSystem.in.read()返回从键盘输入的字符nlSystem.in.read(byteb)从键盘输入多个字符到数组b,并返回字符个数 9.2基本输入输出类nJava有四个最基本的输入输出类:InpuStream、OutputStream、Reader和Writer,Reader和Writer用于字符流的输入输出n9.2.1InputStream(字节输入流)类n9.2.2OutputStream(字节输出流)类n9.2.3Reader(字符输入流)类n9.2.4Writer(字符输出流)类n9.2.5FileReader和FileWriter(字符文件输入/输出流)类9.2.1InputStream(字节输入流)类nInputStream类称作字节输入流类,是一个抽象类。它为其他输入字节流子类提供了一些基本方法和标准接口1.InputStream类的常用方法nlvoidclose()关闭输入流nlvoidmark(intreadlimit)标记输入流的当前位置nlbooleanmarkSupport()测试是否支持mark()方法和reset()方法nlintread(typeb)从输入流读若干个字节到数组b,返回字节个数nlintread(byte,intoff,intlen)n读字节到数组b,起始为off,长度为len,返回字节个数nlvoidreset()复位,即将输入流的当前位置置为初始值nllongskip(longn)跳过n个字节,返回跳过的字节个数nlabstractintread()抽象方法,从输入流读下一个字节 2.异常的抛出nInputStream类中的许多方法在调用时有可能出现异常,例如,调用close()方法关闭文件时,文件因种种原因有可能关闭不了,因此定义的这些方法都有throwsIOException语句。所以,close()方法的完整定义为:voidclose()throwsIOExceptionn应用程序在调用这些方法时,如果不希望由系统进行异常处理,而希望由应用程序进行异常处理,则需要按照8.4.2节讨论的方法进行异常的抛出和异常的处理 3.InputStream类的常用子类nInputStream是抽象类,它本身不能直接用来创建对象,但这个抽象类有很多子类,这些不同子类通过各自定义的抽象父类的抽象方法,实现了各种不同功能的输入字节流。常用的InputStream类的子类以及它们的继承关系如图9.2所示 InputStream类的两个常用子类(1)BufferedInputStream类n当一个BufferedInputStream类对象被创建时,就产生了一个内部缓冲数组,因此,可以根据需要从连接的输入数据流中一次性读多个字节的数据到内部缓冲数组中,这样可以提高读输入数据流的效率nBufferedInputStream的常用构造方法有:nlBufferedInputStream(InputStreamin)nlBufferedInputStream(InputStreamin,intsize)(2)FileInputStream类nFileInputStream类主要用于文件的输入,创建的对象可以顺序地从本地机上的文件中读数据nFileInputStream类常用的构造方法有:nlFileInputStream(Stringname)throwsFileNotFoundExceptionnlFileInputStream(FilefileName)throwsFileNotFoundException9.2.2OutputStream(字节输出流)类nOutputStream类 称 作 字 节 输 出 流 类,也 是 一 个 抽 象 类。OutputStream类为其他的输出字节流子类提供了一些基本方法和标准接口1.OutputStream类的常用方法nlvoidclose()关闭输出流nlvoidflush()清空输出流,使所有缓冲字节写完nlvoidwrite(byteb)将数组b中的字节写到输出流nlvoidwrite(byteb,intoff,intlen)nlabstractvoidwrite(intb)将字节b写到输出流n同样,OutputStream类定义的许多方法都有throwsIOException语句。2.OutputStream类的常用子类nOutputStream是抽象类,它本身不能直接用来创建对象,但这个抽象类有很多子类,这些子类实现了各种具体功能的输出字节流,可以通过实例化它的子类来创建所需的对象n比较常用的OutputStream类的子类以及继承关系如图9.3所示OutputStream类的两个常用子类(1)BufferedOutputStream类nBufferedOutputStream类对象被创建时,产生一个内部缓冲数组,因此,可以从连接的输出数据流中一次性向内部缓冲数组中写多个字节的数据nBufferedOutputStream类的常用构造方法有:nlBufferedOutputStream(OutputStreamout)nlBufferedOutputStream(OutputStreamout,intsize)n(2)FileOutputStream类nFileOutputStream类主要用于文件的输出,它的对象可以顺序地向本地机上的文件中写数据nFileOutputStream类的常用构造方法有:nlFileOutputStream(Stringname)throwsFileNotFoundExceptionnlFileOutputStream(FilefileName)throwsFileNotFoundExceptionnlFileOutputStream(Stringname,booleanapp)throwsFileNotFoundExceptionnBufferedOutputStream类和FileOutputStream类重写了OutputStream类中的write(intb)方法9.2.3Reader(字符输入流)类nReader类称作字符输入流类,是一个抽象类。Reader类为通用的输入字符流提供了一些基本方法和标准接口nReader类定义了两个抽象方法:nlabstractvoidclose()关闭输入字符流nl abstract int raed(charcbuf,intoff,intlen)n读起始位为off、长度为len的若干个字符进数组cbuf中nReader类的子类重写了不同功能的这两个抽象方法nReader类和InputStream类的很多方法很相似,它们的主要区别是:InputStream类操作的是字节,Reader类操作的是字符 Reader类的常用子类继承关系n常用的Reader类的子类以及子类的继承关系如图9.4所示Reader类的两个常用子类(1)BufferedReader类nBufferedReader称作缓冲字符输入流,它在字符输入流的基础上,增加了字符缓冲的功能nBufferedReader类的构造方法有:nlBufferedReader(Readerin)nlBufferedReader(Readerin,intsize)(2)InputStreamReader类n从BufferedReader类的构造方法可以看出,其参数只能是Reader类的对象,而代表标准输入的System.in是一个InputStream类的对象,所以需要将InputStream类的对象转换成Reader类的对象,这就需要一个转换器。InputStreamReader类是将字节输入流转换成字符输入流的转换器。nInputStreamReader类的构造方法有:nlInputStreamReader(InputStreamin)nlInputStreamReader(InputStreamin,Stringenc)nthrowsunsupportedEncodingException9.2.4Writer(字符输出流)类n1.Writer类及其子类nWriter类称作字符输出流类,也是一个抽象类。Writer类为通用的输出字符流提供了一些基本方法和标准接口nWriter类定义了两个抽象方法:nlabstractvoidclose()关闭输出字符流nlabstractintwrite(charcbuf,intoff,intlen)n将指定数组cbuf中字符写到输出流,其起始位置为off,长度为lennWriter类的子类通过重写这两个抽象方法,实现了不同功能的写输出流nWriter类和OutputStream类的很多方法很相似,它们的主要区别是:OutputStream类操作的是字节,Writer类操作的是字符 Writer类及其子类的继承关系 2.PrintWriter(屏幕字符输出流)类nPrintWriter称作屏幕字符输出流类,它主要用来把字符输出流做屏幕输出。n常用的构造方法有:nlPrintWriter(OutputStreamout)nlPrintWriter(OutputStreamout,booleanautoFlush)n常用的方法有:nlvoidprint(Strings)打印字符串snlvoidprintln(Strings)打印字符串s并换行nlvoidprint(Objectobj)打印对象objnlvoidprintln(Objectobj)打印对象obj并换行 9.2.5FileReader和FileWriter(字符文件输入/输出流)类nFileReader类是Reader类的子类的子类,FileWriter类是Writer类的子类的子类1.FileReader类nFileReader称作字符文件输入流。FileReader类常用的构造方法是:nlFileReader(StringfileName)2.FileWriter类nFileWriter称作字符文件输出流。FileWriter类常用的构造方法是:nlFileWriter(StringfileName)9.3对象流n对象都有一定的生命周期。一个对象包含了它生命周期当前的状态。有时候,需要将一个对象生命周期的某一阶段的状态保存下来,当需要的时候,再将保存的对象状态恢复。对象流可以实现这样的功能。对象流有对象输入流ObjectInputStream类和对象输出流ObjectOutputStream类。n对象流中的对象通常不止一个,为了保证保存和恢复的对象不会出错(对错位置),必须保证这些对象都是序列化的对象。序序列列化化的的对对象象是指能够按顺序操作对象流中的对象。一个类,如果实现了Serializable接口,它的对象就是序列化的对象。1.Serializable接口nSerializable接口的定义如下:publicinterfaceSerializable()n这个接口是空的,其中没有定义任何方法,因此实现这个接口非常简单,仅需在类定义时,包含implementsSerializable就可以了 对象输入流和对象输出流 2.对象输入流ObjectInputStream类nObjectInputStream是InputStream的子类,它主要用于对象的恢复。nObjectInputStream类的构造方法有:nlObjectInputStream()nlObjectInputStream(InputStreamin)nObjectInputStream类的常用方法:nlfinalObjectreadObject()恢复对象3.对象输出流 ObjectOutputStream类nObjectOutputStream是OutputStream的子类,它主要用于对象的保存。nObjectOutputStream类的构造方法有:nlObjectOutputStream()nlObjectOutputStream(OutputStreamout)nObjectOutputStream类的常用方法有:nlfinalObjectwriteObject(Objectobj)保存对象obj9.4文件的操作n在程序的运行过程中,经常需要从文件中读取数据或将运行的结果存入文件中,在前面的例子中,这类操作我们都只给出了文件名,这样就只能在当前工作目录下操作文件。实际上,复杂的文件操作还需要知道文件的路径、文件的长度等等许多信息n9.4.1File(文件)类及其应用n9.4.2RandomAccessFile(随机存取文件)类9.4.1File(文件)类及其应用1.File类的构造方法nlFile(Stringname)nlFile(Filepath,Stringname)nlFile(Stringpath,Stringname)2.File类的主要方法nlbooleancanRead()是否可读nlbooleancanWrite()是否可写nlbooleanisFile()是否是文件nlbooleanisDirectory()是否是目录nlbooleanexists()是否存在nllonglength()返回文件的长度nllonglastModified()返回文件的最后修改时间nlStringgetName()返回文件名nlStringgetPath()返回文件的路径nlStringgetParent()返回文件的上一级目录9.4.2RandomAccessFile(随机存取文件)类n前面讲到的文件读写都是按照顺序进行的,本节介绍RandomAccessFile类。RandomAccessFile类称作随机存取文件类,它提供了随机访问文件的方法。和前面讨论的输入输出流类相比,RandomAccessFile类有两点不同:(1)RandomAccessFile类是直接继承自对象类Object,同时实现了DataInput接口和DataOutput接口n(2)由 于 RandomAccessFile类 实 现 了 DataInput 接 口 和DataOutput接口,所以,RandomAccessFile类既可以作为输入流,又可以作为输出流nRandomAccessFile类之所以允许随机访问文件,是由于它定义了一个文件当前位置指针,文件的存取都是从文件当前位置指针指示的位置开始的。通过移动这个指针,就可以从文件的任何位置开始进行读/写操作 RandomAccessFile类构造方法和常用方法1.构造方法nlRandomAccessFile(Filefile,Stringmode)throwsFileNotFoundExceptionnlRandomAccessFile(String name,String mode)throwsFileNotFoundException2.常用方法nllonggetFilePointer()返回文件指针nllonglength()返回文件长度nlvoidseek(longposition)文件指针到达位置positionnlintread()从文件读入一个字节nlintread(byteb)从文件读入b.length个字节存入数组b中nlintread(byte,intoff,intlen)nlStringreadLine()从文件读入一行字节nlvoidwrite(intb)向文件中写入字节bnlvoidwrite(byteb)把数组b中的字节全部写入文件中nlvoidwriteChars(Strings)向文件中写入字符串s