chapter12 输入和输出流处理_第1页
chapter12 输入和输出流处理_第2页
chapter12 输入和输出流处理_第3页
chapter12 输入和输出流处理_第4页
chapter12 输入和输出流处理_第5页
已阅读5页,还剩57页未读 继续免费阅读

下载本文档

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

文档简介

1、第11章 输入和输出流处理,教学目标,输入和输出流概述 输入流和输出流 字节流和字符流 输入和输出类的继承层次结构 File类 基于字节的输入和输出类及应用实例 抽象类InputStream和OutputStream FileInputStream和FileOutputStream类 随机访问文件类 过滤字节流,教学目标(续),标准输入输出流 对象流 管道流 内存读写流 序列输入流 基于字符的输入和输出类及应用实例 InputStreamReader和OutputStreamWriter类 BufferedReader和BufferedWriter类 其它字符流,11.1 输入和输出流概述,本

2、节概述输入流和输出流、字节流和字符流的概念,以及处理输入和输出流相关的系统的类所在的包以及类的继承层次结构,为学习后续的各节打下了基础。,11.1.1 输入流和输出流,程序往往需要输入/输出处理, 比如从键盘读取数据、向屏幕中输出数据、从文件中读数据或者向文件中写数据、在一个网络连接上进行读写操作等。 在Java中,把这些不同类型的输入、输出源抽象为流(Stream) 而其中输入或输出的数据则称为数据流(Data Stream),用统一的接口来表示。数据流是指一组有顺序的、有起点和终点的字节集合。,11.1.1 输入流和输出流,Java的流分类: 输入流(Input Stream):输入流是能

3、够读取字节序列的对象, 和输出流(Output Stream):输出流是能够写字节序列的对象。 如一个文件,当向其中写数据时,它就是一个输出流;当从其中读取数据时,它就是一个输入流。例如,键盘是一个输入流,屏幕是一个输出流。,11.1.2 字节流和字符流,Java 2定义了两种类型的流: 字节流:以byte(8 bits)为基本处理单位的流,这些类分别由抽象类InputStream和OutputStream派生的类层次。 字符流:处理使用Unicode(每个字符使用两个字节)的数据,是从抽象类Reader和Writer的派生的类层次,用于读写双字节的Unicode字符.,面向字节流的输入输出类

4、层次结构,面向字符流的输入输出类层次结构,11.2 File类,File类主要用于获取磁盘中文件或目录的各种信息。 构造File类的对象的构造函数: public Fle(String pathName) 指定与File对象关联的文件或目录的名称。 pathName可以是包含路径信息的文件名或目录名。路径可为绝对路径或为相对路径。,11.2 File类(续),例如: File f=new File(“datatemp.dat”); /相对路径 File g=new File(“d:javadatatemp.dat”); /绝对路径 File类的一些常见方法: String getName():

5、 返回文件名; String getParent():返回文件所在目录名; String getPath(): 返回文件路径; String getAbsolutePath():返回绝对路径; boolean exists(): 文件是否存在; boolean canWrite(): 文件是否可写、读;,11.2 File类(续),boolean isFile(): 是否为文件 boolean isDirectory():是否为目录; long lastModified() :文件的最后修改日期; long length(): 返回文件的长度; boolean delete(): 删除文件或目

6、录。删除成功返回true,否则返回false; boolean mkdir(); 创建一个目录。目录创建成功,返回true,否则返回false; String list(): 返回一个代表目录下的所有文件的字符串数组。,11.2 File类(续),例如 File f=new File(“datatemp.dat”); 上述引用变量f调用相应的方法,得到的值: f.getName(): 返回 temp.dat f.getParent(): 返回 data f.getPath(): 返回 datatemp.dat f.getAbsolutePath():返回 d:javadatatemp.dat

7、f.exists(): 若datatemp.dat文件存在返回 true,否则返回false,11.2 File类(续),File类另一构造函数: public File(URI uri) 使用给定的URI(uniform resource identifier,URI)对 象来定位文件。用于定位Web站点上的资源. 例如, file:/c:/data.txt 指定文件data.txt存储在c盘的根目录下。,11.3 基于字节的输入和输出类及应用实例,抽象类InputStream和OutputStream FileInputStream和FileOutputStream类 随机访问文件类 过滤

8、字节流 标准输入输出流 对象流 管道流 内存读写流 序列输入流,抽象类InputStream和OutputStream,Java中每一种字节流的基本功能依赖于基类InputStream(输入流类)和OutputStream(输出流类),它们都是抽象类,不能直接使用。 InputStream和OutputStream类分别声明了基于字节的输入和输出方法。 属于InputStream类的方法: read():从流中读入数据; skip():跳过数据流中指定数量的字节不读,返回值表示实际跳过的字节数; available():返回流中可用字节数; mark():在流中当前位置标记一个位置; rese

9、t():返回上一个标记过的位置,用于从这一位置读取;,抽象类InputStream和OutputStream(续),markSupport():是否支持标记和复位操作; close():关闭流。 在InputStream类中,方法read()提供了三种从流中读数据的方法: int read():从输入流中读一个字节,形成一个0255之间的整数返回; int read(byte b):读多个字节到数组中,填满整个数组; int read(byte b, int off, int len):从输入流中读取长度为len的数据,写入数组b中从索引off开始的位置,并返回读取得字节数。 对于上面的三个方

10、法,若返回1,表明流结束。,抽象类InputStream和OutputStream(续),属于OutputStream类的方法: write(int b):将一个整数输出到流中(只输出低位字节,为抽象方法); write(byte b):将字节数组中的数据输出到流中; write(byte b, int off, int len):将数组b中从off指定的位置开始,长度为len的数据输出到流中; flush():刷空输出流,并将缓冲区中的数据强制送出; close():关闭流。,FileInputStream和FileOutputStream类 (续),FileInputStream(文件输入

11、流类)和FileOutputStream(文件输出流类)是基于字节的被广泛用于操作顺序文件的两个类。 FileInputStream类: 用于打开一个输入文件。若要打开的文件不存在,则会产生异常FileNotFoundException,这是一个非运行时异常,必须在方法中捕获或向上传递抛出异常。 FileOutputStream类:用于打开一个输出文件。若要打开的文件不存在,则会创建一个新的文件,否则原文件的内容会被新写入的内容所覆盖。如果试图打开一个只读文件,将会引发一个 IOException异常。 在进行文件的读/写操作时,会产生非运行时异常IOException,必须在方法中捕获或向上

12、传递抛出异常。,FileInputStream和FileOutputStream类(续),创建输入文件流对象和输出文件流对象的的语句如下: File f1 = new File(“file1.txt”); /创建File对象 File f2 = new File(“file2.txt”); FileInputStream in=new FileInputStream(f1); /向FileInputStream构造函数传递一个File对象 FileOutputStream out1=new FileOutputStream(f2); /向FileOutputStream构造函数传递一个File

13、对象 FileOutputStream out2=new FileOutputStream(“file3.txt”); 输入流的构造函数的参数是用于指定输入的文件名,输出流的构造函数参数则是用于指定输出的文件名。,public FileOutputStream(Filefile, booleanappend) throws FileNotFoundException Creates a file output stream to write to the file represented by the specified File object. If the second argument

14、is true, then bytes will be written to the end of the file rather than the beginning. A new FileDescriptor object is created to represent this file connection. First, if there is a security manager, its checkWrite method is called with the path represented by the file argument as its argument. If th

15、e file exists but is a directory rather than a regular file, does not exist but cannot be created, or cannot be opened for any other reason then a FileNotFoundException is thrown. Parameters: file - the file to be opened for writing. append - if true, then bytes will be written to the end of the fil

16、e rather than the beginning Throws: FileNotFoundException - if the file exists but is a directory rather than a regular file, does not exist but cannot be created, or cannot be opened for any other reason SecurityException - if a security manager exists and its checkWrite method denies write access

17、to the file.,FileInputStream和FileOutputStream类(续),例10-1 基于字节流的顺序文件的读写。 完成将一文件file1.txt的内容拷贝生成另一新文件file2.txt。,package filestream; import java.io.*; class filestream public static void main(String args) try File inFile=new File(file1.txt); File outFile=new File(file2.txt); FileInputStream fis=new File

18、InputStream(inFile); FileOutputStream fos=new FileOutputStream(outFile); int c; while(c=fis.read()!=-1) fos.write(c); fis.close(); fos.close(); catch(FileNotFoundException e) System.out.println(FileStreamsTest1: +e); catch(IOException e) System.err.println(FileStreamsTest2: +e); ,随机访问文件类,类RandomAcce

19、ssFile可用于随机文件的读写。 随机文件可将每个连续的读写请求定位到文件的任何部分,并且两个读写请求所获得的数据段在文件中可以相差甚远。类RandomAccessFile则允许对文件内容同时完成读和写操作,它直接继承object,并且同时实现了接口DataInput和DataOutput。 DataInput接口中描述了用于从输入流中读取基本类型值的的一组方法,即从输入流中成组地读取字节,并将其视为基本类型值。 DataOutput接口中描述了将基本类型值写入输出流中的的一组方法。,随机访问文件类(续),类RandomAccessFile提供了支持随机文件操作的方法有: XXX ReadX

20、XX():XXX对应基本数据类型。 如int readInt()、 long readLong()、byte readByte()、 char readChar()、 unsignedByte readUnsignedByte()等; void writeXXX():XXX对应基本数据类型。如writeInt、writeLong、writeByte等; String ReadLine():从输入流中读取下一行; int skipBytes(int n):将指针向下移动n个字节; long length():返回文件长度; long getFilePointer():返回指针当前位置; void

21、 seek(long pos):将指针调到所需位置。,随机访问文件类(续),在生成一个随机文件对象时,构造函数的参数,除了要指明File对象或文件名之外,还需要指明访问文件的模式。例如: File f = new File(“file.txt”); new RandomAccessFile(f, “r”); new RandomAccessFile(f, “rw”); new RandomAccessFile(“file1.txt”, “w”); new RandomAccessFile(“file2.txt”, “rw”); 其中“r”是只读模式,“w” 是仅允许写模式,“rw”是可读可写模

22、式。,例11-2随机文件的读写,例11-2 随机文件的读写 将整型数组中的10个数写入随机文件名temp.dat中,并以与写入顺序相反的次序从此文件中读入数据,显示在屏幕上。,import java.io.*; public class random_file public static void main(String args) int data_arr=12,31,56,23,27,1,43,65,4,99; try File f = new File(temp.dat); RandomAccessFile randf=new RandomAccessFile(f,rw); for (i

23、nt i=0;i=0;i-) randf.seek(i*4); System.out.println(randf.readInt(); randf.close(); catch (IOException e) System.out.println(File access error: +e); ,11.3.4 过滤字节流,过滤字节流由Java的类FilterInputStream和FilterOutputStream提供,它们分别对其他输入/输出流(缓冲流、数据流等)进行特殊处理。过滤仅仅意味着可以提供更多的功能,诸如缓冲、监视行数或将数字字节结合成有意义的基本数据类型,它们在读/写数据的同时

24、可以对数据进行特殊处理,另外还提供了同步机制,使得某一时刻只有一个线程可以访问一个输入/输出流。 这两个类FilterInputStream和FilterOutputStream都是抽象类,因此由它们的子类提供额外的功能。,过滤字节流(续),1.带缓冲的过滤字节流 2. 数据过滤流 3. 其他过滤流,1、带缓冲的过滤字节流,类BufferedInputStream(FilterInputStream的子类)和BufferedOutputStream(FilterOutputStream的的子类)是带缓冲的两个过滤字节流。它提供了缓冲机制,把任意的I/O流“捆绑”到缓冲流上,可以提供该I/O流的

25、读取效率。 通过构造函数创建缓冲字节流时,除了要将缓冲流与I/O流相连接之外,还可以指定缓冲区的大小。缺省时用32字节大小的缓冲区,最优的缓冲区大小常依赖于主机操作系统、可使用的内存空间以及机器的配置等,一般缓冲区的大小为内存页或磁盘块的等整数倍,如8912字节或更小。,1、带缓冲的过滤字节流(续),例如: FileInputStream in = new FileInputStream(“file1.txt”); FileOutputStream out = new FileOutputStream (“file2.txt”); BufferedInputStream bin = new B

26、ufferedInputStream(in,256) BufferedOutputStream bout = new BufferedOutputStream(out,256); int len; byte bArray=new byte256; len=bin.read(bArray); /len输入长度, bArray数据 对于BufferedOutputStream,只有缓冲区满时,才会将数据真正送到输出流,但可以使用flush()方法人为地将尚未填满的缓冲区中的数据送出。,2. 数据过滤流,数据过滤流类DataInputStream和DataOutputStream,提供了一种较为高级

27、的数据输入输出方式。它们分别实现了接口DataInput和DataOutput,与RandomAccessFile类似,也属于过滤字节流,但为顺序流。 利用类DataInputStream和DataOutputStream处理字节或字节数组;实现对文件的基本数据类型的数值的读写。 提供的读写方法: read()、readInt()、 readByte()、writeChar()、writeBoolean()、write()等。,2. 数据过滤流(续),通过构造函数创建数据流时,要将缓冲流与I/O流相连接。创建数据流的例子如下: FileInputStream fis = new FileInp

28、utStream(file1.txt); FileOutputStream fos = new FileOutputStream(file2.txt); DataInputStream dis = new DataInputStream(fis); DataOutputStream dos = new DataOutputStream(fos);,2. 数据过滤流(续),例 11-3 利用数据过滤流读写顺序文件 先创建输出数据过滤流,并将输出文件流和输出数据过滤流相连接;向输出数据流顺序写入8个基本类型的数据后,关闭输出数据过滤流(因为是顺序流)。接着,先创建输入数据过滤流,并将输入文件流和输

29、入数据过滤流相连接;从输入数据流顺序读取8个基本类型的数据送显示器显示后,关闭输入数据过滤流。,import java.io.*; /datainput_output.java class datainput_output public static void main(String args) throws IOException FileOutputStream fos = new FileOutputStream(a.txt); DataOutputStream dos = new DataOutputStream (fos); try dos.writeBoolean(true); d

30、os.writeByte(byte)123); dos.writeChar(J); dos.writeDouble(3.141592654); dos.writeFloat(2.7182f); dos.writeInt(1234567890); dos.writeLong(998877665544332211L); dos.writeShort(short)11223); finally dos.close(); ,FileInputStream fin = new FileInputStream(a.txt); DataInputStream sin = new DataInputStrea

31、m (fin); try System.out.println(sin.readBoolean(); System.out.println(sin.readByte(); System.out.println(sin.readChar(); System.out.println(sin.readDouble(); System.out.println(sin.readFloat(); System.out.println(sin.readInt(); System.out.println(sin.readLong(); System.out.println(sin.readShort(); f

32、inally sin.close(); ,3. 其他过滤流,LineNumberInputStream:主要用于对文本文件的处理,提供了行号控制功能。 PushBackInputStream:在编译程序的词法分析阶段,经常要超前读入一个字节以界定当前词的属性,然后再将该字节退回(因为词法分析下面的处理可能还会用到该字节)。 PushBackInputStream就提供了这样的能力,它提供了一个方法将刚刚读入的字节退回到输入流中去。 PrintStream:其作用是将Java语言中的不同类型的数据以字符表示形式输出到相应的输出流中去。,标准输入输出流,Java的标准输入/输出处理则是由包java

33、.lang 中提供的类System实现。在程序开始执行时,Java会自动创建3个与设备关联的六对象:System.in、System.out和System.err对象。 System.in对象(标准输入流对象)是从InputStream中继承而来,用于从标准输入设备中获取输入数据(通常是键盘)。 System.out对象(标准输出流对象)是从PrintStream中继承而来,把输出送到缺省的显示设备(通常是显示器)。 System.err(标准错误流对象),也是从PrintStream中继承而来,把错误信息送到缺省的显示设备(通常是显示器)。,标准输入输出流(续),System类含有标准输入流

34、的静态成员变量in,我们可以调用它的read方法来读取键盘数据。read方法有3种格式: public abstract int read() public int read(byte b) public int read(byte b, int off, int len) 例 11-4 利用标准输入输出流,从键盘输入一行字符串并显示在屏幕上。,import java.io.*; public class ReadFromKeyboard /ReadFromKB.java public static void main(String args) try byte bArray=new byte

35、24; String str; System.out.print(Enter something Using Keyborad:); System.in.read(bArray); str = new String(bArray, 0,bArray.length); System.out.print(You entered:); System.out.println(str); catch(IOException ioe) System.out.println(ioe.toString(); ,对象流,对象流类ObjectOutputStream和ObjectInputStream分别实现了接

36、口ObjectOutput和ObjectInput,并且能够在文件(或其它类型的流)中读取和写入一个完整的对象。 对象的持续性(persistence)指能将对象的状态记录以便将来再生的能力,叫对象的持续性。 对象的可串行化(Serialization)是指对象通过写出描述自己状态的的数值来记录自己的过程。串行化的主要任务是写出对象实例变量的数值。所有基本类型的变量都是可串行化的,如果变量是另一个对象的引用,则引用的对象也要可串行化。这个过程是递归的。,对象流(续),在java中,只有可串行化的对象才能通过对象流进行传输。只有实现Serializable接口的类才能被串行化,Serializa

37、ble接口是一个标记接口(tagging interface),该接口不包含任何方法。当一个类声明实现Serializable接口时,只是表明该类加入对象串行化协议 建立对象输入流时,通常将FileInputStream对象封装在类ObjectInputStream中,用readObject()方法直接从输入流中读取一个对象,此方法的返回类型为Object,往往要转换成当初写入时的对象类型。 建立对象输出流时,通常将FileOutputStream对象封装在类ObjectOutputStream,用writeObject()方法可以直接将对象 写入到输出流中。,对象流(续),例 11-5 使用

38、对象流,对顺序文件进行读写。 程序由两个类Student.java和ObjectSeriWrite.java组成。学生类Student包含信息学号、姓名、年龄和所在系,含有一个构造函数和一个显示学生信息的方法。类Student实现了Serializable接口,是一个可串行化的类,该类的对象是一个可串行化的对象。,import java.io.Serializable; public class Student implements Serializable int id; String name; int age; String departmernt; public Student(int

39、 id, String name, int age, String departmernt) this.id=id; =name; this.age=age; this.departmernt =departmernt; void show() System.out.println(id+,+name+,+age+,+departmernt); ,import java.io.*; class ObjectSeriWrite public static void main(String args) Student stu1=new Student(200501, Li Min

40、g, 16, Compute Science); Student stu2=new Student(200502, Zhang Bi, 17, Chineses); try FileOutputStream fo = new FileOutputStream(student.dat); ObjectOutputStream so = new ObjectOutputStream(fo); so.writeObject(stu1); so.writeObject(stu2); so.close(); FileInputStream fi = new FileInputStream(student

41、.dat); ObjectInputStream si = new ObjectInputStream(fi); stu1=(Student)si.readObject(); stu2=(Student)si.readObject(); stu1.show(); stu2.show(); catch(Exception e) System.out.println(e) ; ,管道流,管道是用来把一个程序、线程和代码块的输出连接到另一个程序、线程和代码块的输入。java.io中提供了类PipedInputStream和PipedOutputStream作为管道的输入/输出流。 管道输入流作为一个

42、通信管道的接收端,管道输出流则作为发送端。管道流必须是输入输出并用,即在使用管道前,两者必须进行连接。,管道流(续),管道输入/输出流可以用两种方式进行连接: (1) 在构造方法中进行连接: PipedInputStream(PipedOutputStream pos); PipedOutputStream(PipedInputStream pis); (2) 通过各自的connect()方法连接: 在类PipedInputStream中,调用方法: connect(PipedOutputStream pos); 在类PipedOutputStream中,调用方法: connect(Piped

43、InputStream pis);,管道流(续),例 11-将数据从输出管道进,从输入管道出 程序将两个byte型数据从输出管道进去,从从输入管道出来,并显示出来。,import java.io.*; class pipedstream public static void main(String args) throws IOException byte aByteData1 = 123, aByteData2 = 111; PipedInputStream pis = new PipedInputStream(); PipedOutputStream pos = new PipedOutp

44、utStream(pis); System.out.println(PipedInputStream); try pos.write(aByteData1); pos.write(aByteData2); System.out.println(byte)pis.read(); System.out.println(byte)pis.read(); finally pis.close(); pos.close(); ,内存读写流,java.io中提供了类ByteArrayInputStream、 ByteArrayOutputStream和StringBufferInputStream以支持 内

45、存的读/写。 ByteArrayInputStream可以从指定的字节数组中读取数据。 ByteArrayOutputStream中提供了缓冲区可以存放数据(缓冲区大小可以在构造方法中设定,缺省为32),可以用write()方法向其中写入数据,然后用toByteArray()方法将缓冲区中的有效字节写到字节数组中去。 StringBufferInputStream与ByteArrayInputStream相类似,不同点在于它是从字符缓冲区StringBuffer中读取16位的Unicode数据,而不是8位的字节数据,序列输入流,java.io中提供了类SequenceInputStream,使

46、应用程序可以将几个输入流顺序地连接在一起,让程序员看起来就像是一个比较长的流一样。 序列输入流提供了将多个不同的输入流统一为一个输入流的功能,这使得程序可能变得更加简洁。,序列输入流(续),例如: FileInputStream f1,f2; String s; f1 = new FileInputStream(“file1.txt”); f2 = new FileInputStream(“file2.txt”); SequenceInputStream fs = new SequenceInputStream(f1, f2); /将文件输入流f1和f2连接在一起 DataInputStrea

47、m ds = new DataInputStream(fs); while( (s = ds.readLine() != null ) System.out.println(s);,11.4 基于字符的输入和输出类及应用实例,Java提供了用于字符流处理的类,它们是以Reader和Writer为基础派生的一系列类,它们是Unicode的用两个字节表示的基于字符的流。 类似于InputStream、OutputStream类,Reader、Writer都是抽象类,这两个类提供了一组用于处理字符流的接口;接口中声明的方法,也与InputStream和OutputStream类似,只不过其中的参数换

48、成字符或字符数组。 例如: String readLine();/ 其返回类型是字符串型,InputStreamReader和OutputStreamWriter类,InputStreamReader(Reader的子类)和OutputStreamWriter(Writer的子类)是用于处理字符流的最基本的类,用来在字节流和字符流之间作为中介。在进行字符处理时,这两个类在构造函数中应指定一定的平台规范,以便把以字节方式表示的流转换为特定平台上的字符表示。 InputStreamReader类和OutputStreamWriter类的构造函数: InputStreamReader(InputStream in); /缺省规范 InputStreamReader(InputStream in, String enc); /指定规范encode,InputStreamReader和OutputStreamWriter类(续),OutputStreamWriter(OutputStream out); /缺省规范 OutputStreamWriter(OutputStream out, String enc); /指定规范encode 如果读取的字符流不是来

温馨提示

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

评论

0/150

提交评论