《jAVA2程序设计基础第十章.ppt》由会员分享,可在线阅读,更多相关《jAVA2程序设计基础第十章.ppt(35页珍藏版)》请在三一办公上搜索。
1、第10章 I/O系统,教学提示:从本章开始,将介绍Java中较为高级的内容。本章介绍Java的I/O(输入/输出)系统,主要包括文件的基本操作,Java 中流的概念及其应用,以及随机访问文件。学习完本章内容后,读者对Java的I/O系统将有一个整体上的认识,并有能力实现一般的输入/输出应用。,教学目标:熟悉对文件及目录的基本操作,熟悉Java I/O系统中各个类的作用及它们之间的关系,掌握随机访问文件的方法。通过上机实践,掌握上述内容的综合应用。,10.1 文件的基本操作,对于任何程序设计语言的I/O系统来说,在对文件进行读写数据操作(不管以何种方式进行)之前,如何找到或定位正确的文件(或目录
2、),如何获取文件(或目录)的属性信息(如是否只读、修改时间、文件大小等),如何创建和删除文件(或目录),是首先必须解决的基础性问题。对文件(及目录)的这些基本操作,是整个 I/O 系统的基石。本节就先介绍Java 提供的用以协助处理文件(及目录)相关事务的类File。,10.1.1 获取文件名清单,10.1.2 获取文件属性信息,10.1.3 建立和删除文件,10.1.1 获取文件名清单,类File的名字很容易让人产生误解,以为 File 对象代表的就是文件,事实上并不只是如此。File对象不仅可以与文件建立关联,而且可以与目录建立关联,还可以与一组文件或目录建立关联,甚至可以及一组文件及目录
3、的混合体建立关联。如果 File对象与一组文件或目录甚至这两者的混合体相关联,可以使用该对象的list()方法获取它们的名称列表。list()方法返回一个 String 数组,每个数组元素为一个文件或目录的名称。,返回,10.1.2 获取文件属性信息,File对象拥有很多获取相关联文件的属性信息的方法,它们的详细介绍见表10.1。,返回,返回,10.1.3 建立和删除文件,File对象中关于建立和删除文件(或目录)的方法见表10.2。,返回,表10.2 File对象建立和删除文件的方法,返回,10.2 流 概 述,所谓流,是指任何可以产生数据的数据源,或任何可以接收数据的接收端,在数据源或接收
4、端与使用流的程序之间的是一个数据序列,其中的数据以字节或字符为单位顺序排列。在往流中写入数据的一端观察,这个流即为输出流;相反,在从流中读出数据的一端观察,这个流即为输入流。流是有方向性的,不能往一个输入流中写数据,也不能从一个输出流中读数据。,10.3 字 节 流,InputStream/OutputStream继承体系中各子类的说明见表10.3和表10.4。,FilterInputStream和FilterOutputStream各子类的说明见表10.5和表10.6。,10.3.1 ByteArrayInputStream,10.3.2 ByteArrayOutputStream,10.3
5、.3 FileInputStream,10.3.5 FilterInputStream,10.3.4 FileOutputStream,10.3.7 SequenceInputStream,10.3.6 FilterOutputStream,表10.3 InputStream的子类,返回,表10.4 OutputStream的子类,返回,表10.5 FilterInputStream的子类,返回,表10.6 FilterOutputStream的子类,返回,10.3.1 ByteArrayInputStream,ByteArrayInputStream对象中有一个字节数组(byte)类型的属性
6、,作为内部缓冲区。类ByteArrayInputStream有两个构造方法,一个构造方法以一个字节数组作为参数,其数据被完全复制给内部缓冲区;另一个构造方法的参数包括一个字节数组、一个整型偏移量和一个整型长度,与前一个构造方法不同的是,此构造方法生成的内部缓冲区将以指定偏移量位置作为起始位置,并且能读取的最大数据长度为指定长度值。这个字节数组就是该输入流的数据源。内部缓冲区保持一个标记,指向当前字节。read()方法读取该标记所指字节的数据,并将该标记向后移一个字节,使下一个字节成为当前字节;通过mark()方法可以在当前字节处做一个记号,通过 reset()方法可以将该记号所指的字节恢复为当
7、前字节,缓冲区标记重新指向该字节;通过 skip()方法可以使缓冲区标记向后跳跃。,返回,10.3.2 ByteArrayOutputStream,与ByteArrayInputStream对应,ByteArrayOutputStream对象中同样有一个字节数组类型的属性,作为内部缓冲区,同时也是该输出流的接收端。类ByteArrayOutputStream有两个构造方法,一个构造方法没有参数,生成的内部缓冲区的初始大小为32个字节,另一个构造方法有一个整型参数,生成的内部缓冲区的初始大小即为该整型参数,内部缓冲区大小将随着数据的写入自动更改。ByteArrayOutputStream 对象通
8、过write()方法往内部缓冲区中写入数据;通过toByteArray()和toString()可以获取内部缓冲区的所有数据;通过 reset()方法可以清空内部缓冲区数据,使数据的写入重新开始;通过 writeTo()方法可以将内部缓冲区的所有数据写入另一个输出流中。,返回,10.3.3 FileInputStream,FileInputStream对象的数据源为文件,其构造方法有3个,一个以文件名为参数,一个以File对象为参数,它们的作用是显然的,只有一点值得注意,若关联的是目录或指定文件不存在,则会产生异常。比较特别的是以FileDescriptor对象为参数的构造方法。FileDes
9、criptor 也是 java.io包中的类,用于关联已打开的文件,或已打开的网络链接,或其他 I/O连接,在机器底层发挥作用,可以强制系统缓冲区与底层设备(文件、网络连接和其他I/O连接都是底层设备)保持同步,从而为输入流或输出流提供一个与底层设备同步的系统缓冲区。这个类并不常用。,返回,10.3.4 FileOutputStream,FileOutputStream对象同FileInputStream一样与文件关联,该文件就是其接收端。写入FileOutputStream对象中的数据将最终写入其关联文件。类FileOutputStream的构造方法有4个,其中 3个分别以关联文件名、Fil
10、e 对象和FileDescriptor对象为参数,与FileInputStream 相应的3 个构造方法中的参数作用相同,另一个构造方法以关联文件名和一个布尔值为参数,该布尔值若为true,则往 FileOutputStream 对象中写入的数据将从关联文件的末尾处开始写入,否则将从关联文件的开头处开始写入,这将覆盖原有数据,参数只有关联文件名的构造方法,相当于此布尔值为 false。关联文件是否有效,不存在时是否可能被创建,视不同操作系统平台不同可能不同。在某些操作系统平台下,同时只允许一个 FileOutputStream 对象关联一个以写方式打开的文件。FileOutputStream
11、对象的方法比较简单,主要通过 write()方法往系统缓冲区中写入数据,通过 flush()方法把系统缓冲区的数据刷新提交到关联文件中。,返回,10.3.5 FilterInputStream,类FilterInputStream的构造方法是受保护的(protected),无法直接创建FilterInputStream对象,本章将直接介绍其子类。由于类LineNumberInputStream已经不建议使用,类PashbackInputStream也极少使用,本书将不作介绍。,返回,10.3.6 FilterOutputStream,类FilterOutputStream的构造方法也是受保护的
12、(protected),同样无法直接创建其对象,本章也将直接介绍其子类。,返回,10.3.7 SequenceInputStream,表10.15 SequenceInputStream对象的方法,返回,10.4 字 符 流,Reader/Writer继承体系中各类与InputStream/OutputStream继承体系中相应类的作用基本相同,区别在于前者基于16位的Unicode编码字符进行读取和写入操作,这两个继承体系之间的对应关系见表10.16。,10.4.2 CharArrayWriter,10.4.1 CharArrayReader,10.4.3 InputStreamReader
13、,10.4.4 OutputStreamWriter,10.4.5 FileReader,10.4.7 StringReader,10.4.6 FileWriter,10.4.8 StringWriter,10.4.9 BufferedReader,10.4.10 LineNumberReader,10.4.12 PrintWriter,10.4.11 BufferedWriter,表10.16 InputStream/OutputStream继承体系与Reader/Writer继承体系的对应关系,返回,10.4.1 CharArrayReader,CharArrayReader 对象中有一个
14、字符数组(char)类型的属性,作为内部缓冲区。类CharArrayReader有两个构造方法,其中一个构造方法以一个字符数组作为参数,另一个构造方法的参数包括一个字符数组、一个整型偏移量和一个整型长度,意义与ByteArrayInputStream对象相同。,返回,10.4.2 CharArrayWriter,与ByteArrayOutputStream对应,CharArrayWriter对象中有一个字符数组类型的属性作为内部缓冲区,同时也是该字符输出流的接收端。类CharArrayWriter有两个构造方法,其中一个构造方法没有参数,生成的内部缓冲区的初始大小为默认值,另一个构造方法有一个
15、整型参数,生成的内部缓冲区的初始大小即为该整型参数,内部缓冲区大小将随着数据的写入自动更改。,返回,10.4.3 InputStreamReader,类InputStreamReader是所谓桥类之一,用于将字节输入流转换成字符输入流,其自身是字符输入流,其数据源是字节输入流。InputStreamReader对象往往被作为其他字符输入流的数据源使用。,返回,10.4.4 OutputStreamWriter,类OutputStreamWriter是所谓桥类中的另一个,用于将字符输出流转换成字节输出流,其自身是字符输出流,其接收端是字节输出流。OutputStreamWriter对象往往被作为
16、其他字符输出流的接收端使用。该类有4个构造方法,一个构造方法以一个字节输出流对象为参数,为要转换成的字节输出流,采用默认的字符编码格式转换字符输出流中的字符数据为字节数据;一个构造方法以一个字节输出流对象和一个字符串为参数,这个字符串为字符编码名称,表示使用何种字符编码格式转换字符输出流中的字符数据;一个构造方法以一个字节输出流对象和一个Charset对象为参数(JDK 1.4中新加入的构造方法),后者指定采用何种字符集转换字符输出流中的字符数据,请参阅Java(JDK 1.4)API文档;另一个构造方法以一个字节输出流对象和一个CharsetEncoder对象为参数(JDK 1.4中新加入的
17、构造方法),后者指定采用何种字符集编码器转换字符输出流中的字符数据,CharsetEncoder为字符集编码器类,代表将字符序列转换成字节序列的引擎,请参阅Java(JDK 1.4)API文档。,返回,10.4.5 FileReader,FileReader是InputStreamReader的子类,与FileInputStream对应,用于读取关联文件中的数据。其构造方法有3个,一个以文件名为参数,一个以File对象为参数,一个以FileDescriptor对象为参数(参见10.3.3小节),这些构造方法都假设默认的编码格式和默认的字节缓冲区是合法的。FileReader的方法都直接继承自其
18、父类InputStreamReader,甚至没有进行任何重载,,返回,10.4.6 FileWriter,FileWriter是OutputStreamWriter 的子类,与 FileOutputStream 对应,用于往关联文件中写入数据。其构造方法有5个,一个以文件名为参数,一个以File对象为参数,一个以FileDescriptor对象为参数(参见10.3.3小节),另两个构造方法分别以关联文件名和一个布尔值,以及File对象和一个布尔值(JDK 1.4中新加入的构造方法)为参数,该布尔值若为true,则往FileWriter对象中写入的数据将从关联文件的末尾处开始写入,否则将从关联文
19、件的开头处开始写入,这将覆盖原有数据,参数只有关联文件名或File对象的构造方法,相当于此布尔值为false。这些构造方法都假设默认的编码格式和默认的字节缓冲区是合法的。FileWriter的方法都直接继承自其父类 OutputStreamWriter,同样没有进行任何重载,在此不一一列出,,返回,10.4.7 StringReader,StringReader对象与一个字符串关联,其构造方法以一个字符串为参数,作为数据源,其方法与 CharArrayReader 完全相同,ready()方法同样始终返回true,因为字符串输入流同样始终为read()方法作好准备。,返回,10.4.8 Str
20、ingWriter,StringWriter对象中有个StringBuffer对象作为内部缓冲区,同时也是该字符输出流的接收端。类StringWriter有两个构造方法,一个构造方法没有参数,生成的缓冲区长度为默认值,另一个构造方法有一个整型参数,生成的内部缓冲区的初始大小即为该整型参数,内部缓冲区大小将随着数据的写入自动更改。,返回,10.4.9 BufferedReader,BufferedReader提供具有缓冲能力的字符输入流,其工作原理与BufferedInputStream相同,同样拥有一个内部缓冲区,但以一个字符输入流为数据源。类BufferedReader有两个构造方法,其中一
21、个以一个字符输入流对象为参数,作为数据源输入流,内部缓冲区大小为默认值;另一个以一个字符输入流对象和一个整数为参数,该整数用于指定内部缓冲区的大小。,返回,10.4.10 LineNumberReader,LineNumberReader是BufferedReader的子类,同样具有缓冲功能,拥有其一切特征,并提供一种按行读取数据的机制,其中一行结束的标志为换行符(n)或回车符(r)或回车符后紧跟一个换行符(回车换行符)。类LineNumberReader有两个构造方法,一个以一个字符输入流对象为参数,作为数据源输入流,内部缓冲区大小为默认值;另一个以一个字符输入流对象和一个整数为参数,该整数
22、用于指定内部缓冲区的大小。LineNumberReader在BufferedReader的基础上增加了两个方法,setLineNumber()用于为当前行编号,其后续行的编号将在此编号的基础上递增,getLineNumber()用于获取当前行的编号,默认情况下行编号从0开始。,返回,10.4.11 BufferedWriter,BufferedWriter提供具有缓冲能力的字符输出流,其工作原理与BufferedOutputStream相同,同样拥有一个内部缓冲区,但以一个字符输出流为接收端。类BufferedWriter有两个构造方法,一个以一个字符输出流对象为参数,作为接收端输出流,内部缓
23、冲区大小为默认值;另一个以一个字符输出流对象和一个整数为参数,该整数用于指定内部缓冲区的大小。一般情况下,BufferedWriter对象会将写入的数据立即提交到接收端输出流,因而flush()方法在此没有明显作用。newLine()方法写入一个由操作系统定义的行分隔符,在Windows操作系统中行分隔符即换行符(n),但并不是所有的操作系统都是如此,因此在需要换行写入数据时建议使用newLine()方法而不是写入一个换行符。,返回,10.4.12 PrintWriter,PrintWriter与PrintStream非常相似,它同样以一种便利的方式将各种数据类型的数据打印至另一个作为接收端的
24、输出流(可以是字节输出流,也可以是字符输出流)中。与PrintStream的不同之处除了它基于字符外,其flush()方法只有在调用println()方法时才自动执行,而不是在写入一个换行符(n)时自动执行,println()方法使用操作系统定义的行分隔符而不一定是换行符(n)。PrintWriter 同样不会产生 IOException 异常,而且同样采用一个内部标志用于记录异常状态,该内部标志值通过checkErr()方法获得。,返回,10.7 上 机 指 导,在本次上机指导中,将给出一个文件操作的综合实例,针对前面几节中的内容进行实际上机练习,目的是让读者了解如何结合各种输入输出流用于实际应用,进一步熟悉输入输出流的使用。通过理解该例,读者将有能力解决其他实际应用中碰到的I/O问题。,