第7章输入输出流 Java程序设计及应用.ppt_第1页
第7章输入输出流 Java程序设计及应用.ppt_第2页
第7章输入输出流 Java程序设计及应用.ppt_第3页
第7章输入输出流 Java程序设计及应用.ppt_第4页
第7章输入输出流 Java程序设计及应用.ppt_第5页
已阅读5页,还剩59页未读 继续免费阅读

下载本文档

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

文档简介

09.06.2020,第7章输入输出流,1,第7章输入输出流,7.1流概述7.2基本输入输出流7.3标准输入输出7.47.5本章小结输入输出流是Java中输入输出功能的基础,是最基本的操作,许多程序需要读写数据都离不开I/O方法。本章主要讲述了流、输入输出流、InputStream类、OutputStream类、Reader类和Writer类,同时介绍了标准输入和输出和文件处理。,09.06.2020,第7章输入输出流,2,7.1流概述,流一般分为输入流(InputStream)和输出流(OutputStream)两类。输入流将外部设备数据引入到计算机中,例如从网络中读取信息,从扫描仪中读取图像信息等;输出流将数据引导到外部设备(屏幕或文件),例如向网络中发布信息,在屏幕上显示图像和文件内容等。但这种划分并不是绝对的。比如一个文件,当向其中写数据时,它就是一个输出流;当从其中读取数据时,它就是一个输入流。当然,键盘只是一个数入流,而屏幕则只是一个输出流。因此,可以将“流”看作数据从一种设备流向另一种设备的过程。它的最大特点是数据的获取和发送均按数据序列顺序进行:每一个数据都必须等待排在它前面的数据读入或送出之后才能被读写,而不能随意选择输入输出的位置。磁带机是实现流式输入输出的较为典型的设备。输入流(InputStream)即数据从外部世界流向计算机。输出流(OutputStream)即是数据从计算机流向外部世界。,09.06.2020,第7章输入输出流,3,7.1流概述,基本输入输出流基本的输入输出类是最简单的类,它用来处理普通的流。其它的派生类是针对某些特定种类的输入或输出。这些类都包含在java.io包中。图7.1输入输出流的操作,09.06.2020,第7章输入输出流,4,7.1流概述,流的分类,09.06.2020,第7章输入输出流,5,7.1流概述,字节流从InputStream和OutputStream派生出来的一系列类。这类流以字节(byte)为基本处理单位。InputStream、OutputStreamFileInputStream、FileOutputStreamPipedInputStream、PipedOutputStreamByteArrayInputStream、ByteArrayOutputStreamFilterInputStream、FilterOutputStreamDataInputStream、DataOutputStreamBufferedInputStream、BufferedOutputStream字符流从Reader和Writer派生出的一系列类,这类流以16位的Unicode码表示的字符为基本处理单位。Reader、WriterInputStreamReader、OutputStreamWriterFileReader、FileWriterCharArrayReader、CharArrayWriterPipedReader、PipedWriterFilterReader、FilterWriterBufferedReader、BufferedWriterStringReader、StringWriter,09.06.2020,第7章输入输出流,6,7.1流概述,Java.io这个软件包包含的两个抽象类,InputStream和OutputStream。所有其它字符数据流的输入/输出类都要扩展这两个基类。java.io软件包提供了一些类和接口,它们在由InputStream和OuputStream类提供的读写操作的顶端定义了一些有用的抽象。例如,ObjectInputStream类提供了让你把输入/输出流中的数据当成对象来读取的方法,而ObjectOutputStream类提供了让你能够把Java对象写入数据流中的方法。这两个类均为抽象类,也就是说它们不能被实例化,必须子类化之后才能够实现一定的功能。InputStream超类提供字符输入流的编程接口和具体实现。OuputStream定义写字节或字节型数组的方法。与输入流InputStream类似,一个输出流在创建时就自动打开,也可以用close()方法显示关闭一个输出流,或者在对象不再被引用,这个OuputStream要成为收集的垃圾时隐式地关闭。java.io包包含若干个实现具体输入或输出的InputStream和OuputStream的子类。例如:FileInputStream和FileOutStream就是在文件系统上进行操作的输入输出流。图7.3和7.4分别表示java.io包中的字节输入流和字节输出流类层次。,09.06.2020,第7章输入输出流,7,7.1流概述,java.io包中字节输入流的类层次,09.06.2020,第7章输入输出流,8,7.1流概述,java.io包中字节输出流的类层次,09.06.2020,第7章输入输出流,9,7.1流概述,包中字符输入流的类层次,09.06.2020,第7章输入输出流,10,7.1流概述,java.io包中字符输出流的类层次,09.06.2020,第7章输入输出流,11,7.2基本输入输出流,InputStream类InputStream类是以字节为单位的输入流。数据来源可以是键盘,也可以是诸如Internet这样的网络环境。OutputStream类OutputStream位于OutputStream类层次的最顶层,它是一个抽象类,OutputStream是与InputStream相对应的输出流类,它具有所有输出流的基本功能。,09.06.2020,第7章输入输出流,12,7.2.1InputStream类,InputStream类是以字节为单位的输入流。数据来源可以是键盘,也可以是诸如Internet这样的网络环境。这个类可以作为许多输入类的基类。InputStream类是一个抽象类,因此不能建立其实例类,相反用户必须使用其子类。注意,大多数输入方法都抛出了IOException例外。因此,如果程序中调用拉这些输入方法,就必须捕获和处理IOException例外。类InputStream处于InputStream类层次的最顶层,09.06.2020,第7章输入输出流,13,7.2.1InputStream类,read方法read方法用于从指定的输入流读取以字节为单位的数据,第一次从流的开始位置开始读取,以后每次从上次的结束部位开始读取,即自动实现了位移。read方法有以下三种形态publicintread(bytebuff)throwsIOException该方法以一字节型数组作为参数,可用于一次读取多个字节,读入字节直接放入数组buff中,并返回读取的字节数。使用该方法必须保证数组有足够的大小来保存所要读入的数据,否则Java就会抛出一个IOException。(例7-1)publicabstractintread()throwsIOException即不带参数,该方法每次一个字节从指定的输入流中读取数据。返回值也是int类型,但它并不代表读取的字节数,而是从流中读取的数据的本身,因数据本身是byte类型的,所以一般要强制进行转化;如果没有数据返回的值是-1。在Java中,不能直接把一个整数转换为字符,因为Java的整数为32位,而字符则是为16位。还须注意,该方法一般是通过子类来实现的,所以通常通过System.io.read()来调用。通过以下例题来说明该方法的使用。(例7-2)publicintread(bytebuff,intstart,intlen)从指定流读取数据,从start开始,填充len个字节到buff中,返回值为实际的填充数,如果返回值len,一般表示已将指定流中的数据读完。这个方法还可以用于防止数组越界,其用法是:把start设置为0,len设成数组长度。这样,既可填充整个数组,又能保证不会越界。,09.06.2020,第7章输入输出流,14,7.2.1InputStream类,available方法格式:publicintavailable()throwsIOException功能:返回当前流中可用字节数。available方法用于计算指定流中当前有多少字节,如果指定的流是文件流,那么就返回文件的大小。Available返回的值是int类型。有的输入流可能没有能力返回字节数,如果对这些输入流使用avaiable方法,返回值为0。close方法格式:publicviodclose()throwsIOException功能:关闭当前流对象对于打开的stream,Java可以自动回收,但是Java自动回收需要时间,所以最好自己调用close方法来关闭stream,这样方便下一次重新指定的流。所以,I/O流在使用完后一定不要忘记关闭输入流,使用close()方法执行关闭操作。,09.06.2020,第7章输入输出流,15,7.2.1InputStream类,skip方法格式:publiclongskip(longn)throwsIOException功能:跳过指定的字节数。skip方法类似于C语言中的lseek,都是用于定位的。Skip方法定义:longskip(longn),该方法使指定流中的当前位置移动n个字节,n的值可以是负值用于向前移,skip方法返回值为实际移动的字节数,由于种种原因,如已到流尾或者其它原因返回的值往往小于n。对于读取文件来说,小于n的原因最大的原因是读到了文件尾。InputStream类的几个常用方法还有:publicSynchronizedvoidmark(intreadlimit):在流中标记一个位置。publicSynchronizedvoidreset()throwsIOException:返回流中放标记的位置。publicBooleanmarkSupport():返回一个表示流是否支持标记和复位操作的布尔值。,09.06.2020,第7章输入输出流,16,7.2.1InputStream类,使用InputStream的注意点当程序中调用InputStream进行请求,所调用的方法就处在等待状态,这种状态就是“堵塞”。请分析下面一段程序:Tryint.byt=System.in.read();catch(IOExceptione)System.out.println(e.toString();当程序运行到System.in.read()的时候就等待用户输入,直到用户输入一个回车键为止。InputStream类操作的是字节数据,不是字符。ASCII字符和字节数据对应8位数据,Java的字符为16位数据,Unicode字符集对应16位字节数据,Java的整数为32位。这样,利用InputStream类来接收键盘字符将收不到字符的高位信息。流是通过-1来标记结束的。因此,必须用整数作为返回的输入值才可以捕捉到流的结束。否则,如果使用的是相当于无符号整数的字符来保存,则无法确认流何时结束。从字节输入流InputStream类的层次结构图可以看出,InputStream是所有基于字节的输入流类的超类。由于它本身是抽象类,不能用来直接创建对象,它提供的方法通常是在其子类的对象中被使用的。,09.06.2020,第7章输入输出流,17,7.2.1InputStream类,FileInputStreamFileInputStream是从InputStream中继承下来的,称为文件字节输入流,是将文件作为源端设备和目的端设备进行字节处理的I/O流,也就是说,文件字节输入流读取对象是文件。该类的所有方法都是从InputStream类继承来的。为了创建FileInputStream类的对象,可以使用构造方法:FileInputStream(stringname)和FileInputStream(Filefile)。格式如下:publicFileInputStream(Stringname)throwsFileNotFoundExceptionpublicFileInputStream(Filefile)throwsFileNotFoundException读取方法:publicintread()throwsIOExceptionpublicintread(byteb)throwsIOExceptionpublicintread(byteb,intstart,intlen)throwsIOException该组方法用于从文件中读取数据。其中,b是保存存取到的数据的字节数组,start是输入流的字节偏移量,len是将要读取的字节长度。可以一次一个字节地读取,也可以按字节数组的容量或指定字节长度成批地读取。,09.06.2020,第7章输入输出流,18,7.2.1InputStream类,FileInputStream流顺序地读取文件,只要不关闭流,每次调用read()方法就顺序地读取文件中其余的内容,直到文件的末尾或流被关闭。关闭方法格式如下:(例7_3)publicvoidclose()throwsIOExceptionPipedInputStream管道流用于程序(或线程)之间的通讯。InputStream的派生类PipedInputStream一般与PipedOutputStream一起用构成线程之间双向的通信管道。一个PipedInputStream必须连接一个PipedOutputStream,而且一个PipedOutputStream也必须连接一个PipedInputStream。PipedInputStream用于实现管道的输入端,而PipedOutputStream用于实现管道的输出端。,09.06.2020,第7章输入输出流,19,7.2.1InputStream类,PipedInputStream类用于从管道中读取数据,这个管道数据由PipedOutputStream类写入。因此,在使用类PipedInputStream之前,必须将它连接到类PipedOutputStream。可以在实例化PipedInputStream类时建立这个连接,或者调用Connect()方法建立连接。PipedInputStream中包括用于读数据的底层方法,同时也提供了读数据的高层接口。PipedInputStream类创建的对象称为一个输入管道。在里先不介绍PipedInputStream的具体用法。FilterInputStreamFilterInputStream也是从InputStream中继承下来,不过FilterInputStream类基本上不能直接使用,一般上使用该类的派生类,如BufferedInputStream、DataInputStream、LineNumberInputStream、PushbackInputStream。该类的最大特点是,在定义时可以嵌套:InputStreams=getAnInputStreamFromSomewhere();FilterInputStreams1=newFilterInputStream(s);FilterInputStreams2=newFilterInputStream(s1);FilterInputStreams3=newFilterInputStream(s2);所以该类的所有派生类都具有这个特性。各个派生类简单介绍如下:,09.06.2020,第7章输入输出流,20,7.2.1InputStream类,BufferedInputStream它通过重写其超类FilterInputStream的方法,在其中提供了内部缓冲操作,内部缓冲允许大量待读取的数据存入缓冲区内。即使重写了FilterInputStream的方法,其过滤机器仍保留着。使用内部缓冲,使得实际数据可以按块读取,如按照磁盘的块大小进行读取。其后的读请求由内部缓冲区来响应,这样访问速度比磁盘的访问速度快。使用下面的构造方法中的任何一个都可以建立BufferedInputStream对象:publicBufferedInputStream(InputStreamin);publicBufferedInputStream(InputStreamin,intsize);第一种形式使用一个缺省的缓冲区大小,而第二种形式用构造方法的第二个参数指定缓冲区大小。DataInputStream有许多应用程序需要将处理的数据作为Java的一种基本类型(如布尔型,字节,整数和浮点数)。这就要用到类DataInputStream和DataOutStream.。使用这些类,可以读或写Java基本数据类型组成的流。DataInputStream扩展了FilterInputStream的类,并实现了DataInput接口:publicclassDataInputStreamextendsFilterInputStreamImplementsDataInput,09.06.2020,第7章输入输出流,21,7.2.1InputStream类,LineNumberInputStreamLineNumberInputStream类用于记录输入流中的行号。行号在标记/重置操作中记录。可以用getLineNumber()获得当前的行号,而setLineNumber()可以用于设置当前行的行号。改变某一行的行号后,其后的行就从这个新的行号开始重新编号。类LineNumberInputStream是FilterInputStream类的子类。PushbackInputStreamPushbackInputStream类利用unread()方法,可以将一个字节送回输入流中。送回InputStream中的这个字符可以在下一次调用read()时被读出。PushbackInputStream类可用于实现“先行”功能,它返回下一个要读出的字符。编写用于输入分析的程序时,这个功能很有用。类PushbackInputStream是FilterInputStream类的子类。,09.06.2020,第7章输入输出流,22,7.2.1InputStream类,SequenceInputStreamSequenceInputStream把多个输入流顺序接到一个输入流中,即将不同的InputStream按先后顺序串在一起。使用这个类可以将两个独立的流合并为一个逻辑流,如将两个InputStream串起来:InputStreams1=newFileInputStream(theFirstPart);InputStreams2=newFileInputStream(theRest);InputStreams=newSequenceInputStream(s1,s2);以上只能实现两个输入流的串接,要实现两个以上输入流串接,需要用到Vector类,如下所示:Vectorv=newVector(3);Enumeratione;v.addElement(s1);v.addElement(s2);v.addElement(s2);e=v.elements();InputStreams=newSequenceInputStream(e);合并后的流中的数据按照在各个流中指定的顺序读出。第一个流结束时,使用无缝连接的方式开始从第二个流中读数据。StringBufferInputStream允许程序将一个StringBuffer用作输入流,并使用ByteArrayInputStream从中读取数据。Stringbuffer=Nowisthetimeforallgoodmentocome.;InputStreams=newStringBufferInputStream(buffer);,09.06.2020,第7章输入输出流,23,7.2.1InputStream类,ObjectInputStreamObjectInputStream与ObjectOutputStream相对应,ObjectInputStream类和ObjectOutputStream类分别是InputStream类和OutputStream类的子类。ObjectInputStream类创建的对象被称为对象输入流。对象输入流使用readObject()从源中读取一个对象到程序中。ObjectInputStream将对象的值及类的定义等从指定的输入流读入,以便重新对象化:FileInputStreamin=newFileInputStream(tmp);ObjectInputStreams=newObjectInputStream(in);Stringtoday=(String)s.readObject();Datedate=(Date)s.readObject();ObjectOutputStream和ObjectInputStream就可以实现对象的持久化,即要先将对象序列化保存到介质中,在必要的时候重新恢复这些对象。,09.06.2020,第7章输入输出流,24,7.2.2OutputStream类,OutputStream位于OutputStream类层次的最顶层,它是一个抽象类,OutputStream是与InputStream相对应的输出流类,它具有所有输出流的基本功能。下面列出输出流类对应的方法。writewrite方法与InputStream的read方法相对应,它有三个形态:publicviodwrite(bytebuff)throwsIOException:向流中写入一个字节数组,即将指定buff数组中的数据输出到指定Stream;publicvoidwrite(bytebuff,intoff,intlen)throwsIOException:将指定buff数组中的数据从第二个参数开始,输出第三个参数指定的长度到指定的Stream;publicabstractvoidwirte(intbuff)throwsIOException;将一个int值输出到指定的Stream;flush格式:publicvoidflush()throwsIOException功能:清空流并强制缓冲区中所有数据写入到流中。,09.06.2020,第7章输入输出流,25,7.2.2OutputStream类,Close格式:publicvoidclose()throwsIOException功能:Close用于关闭指定的输出流。使用过程中要注意,OutputStream是抽象类,不能直接建立它的实例,但可以使用如下语句建立输出流对象:OutputStreamos=newFileOutStream(“test.dat”);从字节输出流OutputStream类的层次结构图可以看出,OutputStream是所有基于字节的输出流类的超类。由于它本身是抽象类,不能用来直接创建对象,它提供的方法通常是在其子类的对象中被使用的。以下我们具体介绍一下OutputStream的子类的用法,09.06.2020,第7章输入输出流,26,7.2.2OutputStream类,FileOutputStreamFileOutputStream与FileInputStream相对应,它提供了基本的文件写入能力,称为文件字节输出流。文件字节输出流按字节将数据写入到文件中。为了创建FileOutputStream类的对象,可以使用构造方法:FileOutputStream(stringname)和FileOutputStream(Filefile)。格式如下:publicFileOutputStream(Stringname)throwsFileNotFoundExceptionpublicFileOutputStream(Filefile)throwsFileNotFoundException参数是可以用字符串表示的文件名,也可以是创建时与指定文件关联的文件对象出现异常时将抛出FileNotFoundException异常。构造方法参数指定的文件为输出流的目的地,输出流通过使用write()方法把数据写入输出流到达目的地。write方法的格式如下:publicviodwrite(intb)throwsIOExceptionpublicviodwrite(byteb)throwsIOExceptionpublicviodwrite(byteb,intstart,intlen)throwsIOException该组方法用于向指定文件中写入数据。其中,整型变量b是将要写入的字节的整数值,字节数组b是将要写入的字节数组,start是输出流的字节偏移量,len是将要写入的字节长度。可以一次一个字节地写入,也可以按字节数组的容量或指定字节长度成批地写入。FileOutputStream流顺序地写文件,只要不关闭流,每次调用write()方法就顺序地向文件写入内容,直到流被关闭。如果输出流要写入数据的文件已经存在,该文件中的数据内容就会被刷新;如果要写入数据的文件不存在,该文件就会被建立。(例7-4),09.06.2020,第7章输入输出流,27,7.2.2OutputStream类,PipedOutputStreamPipedInputStream类创建的对象称为一个输入管道,PipedOutputStream类创建的对象称为一个输出管道。输出管道与输入管道连接就形成了一个传输数据的通道。使用这样的管道,用户可以在不同线程之间实现数据共享。也就是说,一个线程中的管道输入流应当指向另一个线程中的管道输出流;而一个线程中的管道输出流应当指向另一个线程中的管道输入流,然后管道输入流就可以读取写入管道输出流的数据了。相应地PipedOutputStream与PipedInputSteam相互配合实现两个线程之间的通信,它们的定义如下:PipedInputStreamsIn=PipedInputStream();PipedOutputStreamsOut=PipedOutputStream(sIn);(例7-5)说明:类ReadThread非常巧妙,它并没有指定输入输出流的具体类型在MyPipe类中newReadThread(reader,System.in,readOut)语句使得从标准输入设备中接收数据,而从readOut输出,而readOut是PipedOutputSteam,所以它可以被另一线程接收;newReadThread(writer,writeIn,System.out),从writeIn接收数据,writeIn是readOut是成对的双向管道,它接收从readOut发送过来的数据。再从标准设备中输出。,09.06.2020,第7章输入输出流,28,7.2.2OutputStream类,FilterOutputStreamFilterOutputStream与FilterInputStream相对应,使用方法也相类似。FilterOutputStream用于建立一个输出过滤器。FilterOutputStream类将另一个输出流作为其类定义的一部分存储。所有FilterOutputStream的方法调用都传递给它的内部输入流。当构造FilterOutputStream实例时,必须传给它一个将在内部存储的输入流的实例。FilterOutputStream类本身并不做任何处理,只是将方法调用传递给它的内部输入流。如果希望它执行有用的处理,必须建立它的子类,并在其中提供必要的操作。FilterOutputStream的标准子类是BufferedOutputStream、DataOutStream、PrintStream。以下将分别介绍这几个子类的使用。BufferedOutputStreamBufferedOutputStream从FilterOutputStream中继承下来,它与BufferedInputStream相对应,作用也相类似,它主要为输出流做缓冲,OutputStreams=newBufferedOutputStream(newFileOutputStream(foo);由于BufferedOutputStream是缓冲数据的,所以必要时,需要使用flush方法强制将缓冲中的数据真正写入输出流中。,09.06.2020,第7章输入输出流,29,7.2.2OutputStream类,DataOutputStreamDataOutputStream与DataInputStream相对应,它执行输入流中基本的Java数据类型的数据输出。在继承OutputStream的同时,实现了DataOutput接口,实现DataOutput接口格式如下:ublicclassDataOutputStreamextendsFilterOutputStreamimplementsDataOutput因此它具有DataOutput接中所规定的方法,这些方法与DataInput所规定的方法相反。它还具有size方法,该方法返回向输出流写入的字节数。以下是实现复制功能的例子:trywhile(true)aDO.writeByte(aDI.readByte();finallyaDI.close();aDO.close();使用下面的低层方法可以建立DataOutputStream的一个实例:publicDataOutputStream(OutputStreamout);,09.06.2020,第7章输入输出流,30,7.2.2OutputStream类,PrintStream为了在标准输出流中提供复杂的输出,提供PrintStream类派生出输出流对象。PrintStream是一个格式化的输出流,是从FilterOutputStream继承下来的。PrintStream的构造函数:(1)PrintStream(booleanautoFlush,OutputStreamout)(2)PrintStream(OutputStreamout)(3)PrintStream(OutputStreamout,booleanautoFlush)(4)PrintStream(OutputStreamout,booleanautoFlush,Stringencoding),09.06.2020,第7章输入输出流,31,7.2.2OutputStream类,ByteArrayOutputStreamByteArrayOutputStream类是将数据写入流的内部字节数组缓冲区,同时,流内部维护一个写入字节的计数器,记录写入的字节数。实际执行时将一个输出流指向一个Byte数组,但这个Byte数组是ByteArrayOutputStream内部内置的,不需要我们来定义。该类有两个构造函数:(1)ByteArrayOutputStream():该构造函数会在内部创建一个长度为32的Byte数组;(2)ByteArrayOutputStream(intn):在对象内部创建一个长度为n的Byte数组。ByteArrayOutputStream从OutputStream类继承下来,所以它具write、flush及close等方法,同时它还具有以下几个特殊的方法:(1)toString():将对象内部的Byte数组转化成字符串(String(buf,0,count);(2)toString(intn):将对象对部的Byte数组转化成字符串,编码方式为n;(3)toString(Stringn):将对象对部的数组转化成字符串,编码方式为n;(4)toByteArray():返回对象内部的Byte数组;(5)writeTo(OutputStream):将内部Byte数组输出到指定的输出流;(6)reset():将对象内部Byte数组的长度设为0,count=0;(7)size():返回Byte数组长度。例7-6,09.06.2020,第7章输入输出流,32,7.2.2OutputStream类,ObjectOutputStreamObjectOutputStream类是用于将原始数据类型以及整个对象写到一个流中。ObjectOutputStream从OutputStream继承下来,并实现了ObjectOutput,ObjectStreamConstants这两个接口。它负责将指定对象输出到指定的输出流,可以将非static、非transient的属性及值、对象的类定义输出到指定的输出流。该类有一个非常用的方法:writeObject(Objectobj);该方法将obj输出到指定的输出流,以下是该类的例子:FileOutputStreamf=newFileOutputStream(tmp);ObjectOutputs=newObjectOutputStream(f);s.writeObject(Today);s.writeObject(newDate();s.flush();可以使用transient修饰符规定一些变量的值不被输出到指定的输出流.,09.06.2020,第7章输入输出流,33,7.2.3Reader类,在JDK1.1之前,java.io包中的流只有普通的字节流(以byte为基本处理单位的流),这种流对于以16位的Unicode码表示的字符流处理很不方便。从JDK1.1开始,java.io包中加入了专门用于字符流处理的类,它们是以Reader和Writer为基础派生的一系列类。除了字节数据外,字符数据也是一种软件经常使用的数据类型,如文本数据的存取处理。Java提供了对字符类型的数据流操作,这就是字符流。与字节流不同,字符流的基本类是Reader类和Writer类。这两个类是所有基于字符的流类的超类。与InputStream和OutPutStream相同,它们也是Object的子类,也是抽象类,只提供了一系列用于字符流处理的接口,不能直接用来创建对象。它们的方法与类InputStream和OutputStream类似,只不过其中的参数换成字符或字符数组,09.06.2020,第7章输入输出流,34,7.2.3Reader类,Reader类是处理所有字符流输入类的父类,Reader类具有以下方法:读取字符publicintread()throwsIOException;/读取一个字符,返回值为读取的字符publicintread(charcbuf)throwsIOException;/读取一系列字符到数组cbuf中,返回值为实际读取的字符的数量publicabstractintread(charcbuf,intoff,intlen)throwsIOException;/读取len个字符,从数组cbuf的下标off处开始存放,返回值为实际读取的字符数量,该方法必须由子类实现标记流publicbooleanmarkSupported();/判断当前流是否支持做标记publicvoidmark(intreadAheadLimit)throwsIOException;/给当前流作标记,最多支持readAheadLimit个字符的回溯。publicvoidreset()throwsIOException;/将当前流重置到做标记处关闭流publicabstractvoidclose()throwsIOException;/关闭输入源。进一步的读取将会产生IOException异常,09.06.2020,第7章输入输出流,35,7.2.3Reader类,以下将分别介绍Reader的各个子类的使用:FileReaderFileReader类创建了一个可以读取文件内容的Reader类。它最常用的构造函数显示如下:FileReader(StringfilePath)throwsFileNotFoundExceptionFileReader(FilefileObj)throwsFileNotFoundException每一个都能引发一个FileNotFoundException异常。这里,filePath是一个文件的完整路径,fileObj是描述该文件的File对象。FileReader类没有自己的实例方法,它的实例方法都是从InputStreamReader继承而来的,读取方法格式如下:Publicintread()throwsIOExceptionpublicintread(charcbuf,intoff,intlen)throwsIOException该组方法用于从文件中读取字符数据。其中,cbuf是保存读取到的数据的字符数组,off是输入流的字符偏移量,len是将要读取的字符数。可以用read()一次一个字符地读取,也可以按字符数组的容量或指定的字符数成批地读取。关闭方法:Publicvoidclose()throwsIOException其他方法:publicStringgetEncoding()该方法获得文件流当前使用的编码机制,返回值是代表编码名称的字符串。(例7-7),09.06.2020,第7章输入输出流,36,7.2.3Reader类,FilterReader是过滤字符输入流的超类。其子类为PushbackReader,它允许将字符推回到流的字符流reader。构造方法如下:PushbackReader(Readerin):创建具有单字符推回缓冲区的新推回reader。PushbackReader(Readerin,intsize):创建具有给定大小推回缓冲区的新推回reader。PushbackReader的方法主要有:voidclose():关闭该流。voidmark(intreadAheadLimit):标记流中的当前位置。booleanmarkSupported():判断此流是否支持mark()操作(它一定不支持)。intread():读取单个字符。intread(charcbuf,intoff,intlen):将字符读入数组的某一部分。booleanready():判断是否准备读取此流。voidreset():重置该流。longskip(longn):跳过字符。voidunread(charcbuf):推回一个字符数组,方法是将其复制到推回缓冲区前面。voidunread(charcbuf,intoff,intlen):推回字符数组的某一部分,方法是将其复制到推回缓冲区的前面。voidunread(intc):推回单个字符。(例7-8),09.06.2020,第7章输入输出流,37,7.2.3Reader类,BufferedReaderBufferedReader类创建的对象称为缓冲输入流,该输入流的指向必须是一个Reader流,称为BufferedReader流的底层流,底层流负责将数据读入缓冲区。BufferedReader流的源就是这个缓冲区,缓冲输入流从缓冲区中读取数据。它有两个构造函数:BufferedReader(ReaderinputStream)BufferedReader(ReaderinputStream,intbufSize)第一种形式创建一个默认缓冲器长度的缓冲字符流。第二种形式,缓冲器长度由bufSize传入。和字节流的情况相同,缓冲一个输入字符流同样提供支持可用缓冲器中流内反向移动的基础。为支持这点,BufferedReader实现了mark()和reset()方法,并且BufferedReader.markSupported()返回true.。(例7-9),09.06.2020,第7章输入输出流,38,7.2.3Reader类,PipedReaderr管道I/O是专门用于线程通信。对于字节流Java提供了两个类,PipedInputStream类和PipedOutputStream类被线程用来读写字节数据。两个管道I/O流对象可以连接起来,这样一个线程写的数据就可以被另一个线程来读。对于字符流也有两个类,分别叫做PipedReader和PipedWriter。由于字节流的PipedInputStream类和PipedOutputStream类和字符流的PipedReader类和PipedWriter类在使用上非常相似,我们只详细介绍字节流的管道I/O类,对于PipedReaderr类和PipedWriter类仅介绍其构造方法和主要方法。PipedReaderr类构造方法如下:publicPipedReader(PipedWritersrc)throwsIOException;/创建连接到传送writersrc的PipedReader。写入src的数据稍后将用作此流的输入。参数src为要连接的流。publicPipedReader();/创建尚未连接的PipedReader。必须在使用之前将其连接到PipedWriter。,09.06.2020,第7章输入输出流,39,7.2.3Reader类,其他方法:publicvoidconnect(PipedWritersrc)throwsIOException;/使此传送reader连接到传送writersrc。如果此对象已经连接到其他某个传送writer,则抛出IOException。src为要连接的传送writer。如果src为未连接的传送writer,而snk为未连接的传送reader,则可以通过以下任一调用使其连接:snk.connect(src)或:src.connect(snk)这两个调用的效果相同。publicintread()throwsIOException;/读取此传送流中的下一个数据字符。如果因流的末尾已到达而没有可用的字符,则返回值-1。在输入数据可用、检测到流的末尾或者抛出异常前,此方法一直阻塞。如果某个线程正向连接的传送writer提供数据字符,但该线程不再处于活动状态,则抛出IOException。publicintread(charcbuf,intoff,intlen)throwsIOException;/将此传送流中最多len数据字符读入字符数组。如果已到达数据流的末尾,则读取的字符数少于len。至少要有一个输入字符可用,否则将阻塞此方法。如果某个线程正向连接的传送输出提供数据字符,但该线程不再处于活动状态,则抛出IOException。cbuf-读入数据的缓冲区。off-数据的初始偏移量。len-读取的最大字符数。返回读入缓冲区的总字符数,如果由于流末尾已到达而不再有数据,则返回-1。publicbooleanready()throwsIOException;/告知是否准备读取此流。如果循环缓冲区不空,则传送字符流已做好被读取准备。如果保证下一个read()不阻塞输入,则返回True,否则返回false。注意,返回false并不保证阻塞下一次读取。publicvoidclose()throwsIOException;/关闭此传送流并释放与该流相关的所有系统资源。,09.06.2020,第7章输入输出流,40,7.2.3Read

温馨提示

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

评论

0/150

提交评论