第8章IO输入输出教学设计.docx
- 文档编号:12129551
- 上传时间:2023-04-17
- 格式:DOCX
- 页数:18
- 大小:71.43KB
第8章IO输入输出教学设计.docx
《第8章IO输入输出教学设计.docx》由会员分享,可在线阅读,更多相关《第8章IO输入输出教学设计.docx(18页珍藏版)》请在冰豆网上搜索。
第8章IO输入输出教学设计
传智播客
《Java基础入门》
教学设计
课程名称:
Java基础教程
授课年级:
2014年级
授课学期:
2014学年第一学期
教师姓名:
某某老师
2014年02月09日
课题名称
第8章IO(输入输出)
计划学时
8课时
内容分析
大多数应用程序都需要实现与设备之间的数据传输,在Java中,将这种通过不同输入/输出设备之间的数据传输抽象表述为“流”。
Java中的“流”都位于java.io包中,称为IO(输入/输出)流,IO流有很多种,本课程将对这些流进行详细的讲解。
教学目标及基本要求
要求学生掌握字节流、字符流、转换流和File类,了解IO中几个比较重要流以外的其它IO流、RandomAccesseFile和字符编码
重点及措施
教学重点:
字节流、字符流、转换流和File类
难点及措施
教学难点:
字节流、字符流、其它IO流、转换流和File类。
本章中内容均有一定的难度,而且涉及的流种类较繁杂,因而理清各种流之间的关系及其各个流的作用,将有助于理解和记忆,同时引导学生结合代码学习也是十分重要的。
教学方式
教学采用教师课堂讲授为主,使用教学PPT讲解
教
学
过
程
第一课时
(字节流、字节流读写文件、文件的拷贝、字节流的缓冲区、、装饰设计模式、字节缓冲流)
字节流
✧字节流分类
字节流分为字节输入流和字节输出流,其中字节输入流继承自InputStream,字节输出流继承自OutputStream。
✧InputStream的常用方法
方法声明
功能描述
inread()
从输入流读取一个8位的字节,把它转换为0~255之间的整数,并返回这一整数
intread(byte[]b)
从输入流读取若干字节,把它们保存到参数b指定的字节数组中,返回的整数表示读取字节数
intread(byte[]b,intoff,intlen)
从输入流读取若干字节,把它们保存到参数b指定的字节数组中,off指定字节数组开始保存数据的起始下标,len表示读取的字节数目
voidclose()
关闭此输入流并释放与该流关联的所有系统资源
✧OutputStream的常用方法
方法名称
方法描述
voidwrite(intb)
向输出流写入一个字节
voidwrite(byte[]b)
把参数b指
的字节数组的所有字节写到输出流
voidwrite(byte[]b,intoff,intlen)
将指定byte数组中从偏移量off开始的len个字节写入输出流
voidclose()
关闭此输出流并释放与此流相关的所有系统资源
voidflush()
刷新此输出流并强制写出所有缓冲的输出字节
字节流读写文件
由于计算机中的数据基本都保存在硬盘的文件中,因此操作文件中的数据是一种很常见的操作。
在操作文件时,最常见的就是从文件中读取数据并将数据写入文件,即文件的读写。
针对文件的读写,JDK专门提供了两个类,分别是FileInputStream和FileOutputStream。
FileInputStream是InputStream的子类,它是操作文件的字节输入流,可以通过重载的read()方法读取文件中的数据。
FileOutputStream是OutputStream的子类,它是操作文件的字节输出流,可以通过重载的write()方法将获取到的数据写入文件。
如果希望在已存在的文件内容之后追加新内容,则可使用FileOutputStream的构造函数FileOutputStream(String fileName,boolean append)来创建文件输出流对象关闭流。
文件的拷贝
在应用程序中,IO流通常都是成对出现的,即输入流和输出流一起使用。
例如文件的拷贝就需要通过输入流来读取文件中的数据,通过输出流将数据写入文件,示例代码如下所示:
//创建一个字节输入流,用于读取当前目录下source文件夹中的mp3文件
InputStreamin=newFileInputStream("source\\tyle.mp3");
//创建一个字节输出流,用于将读取的数据写入target目录下的文件中
OutputStreamout=newFileOutputStream("target\\style.mp3");
intlen;//定义一个int类型的变量len,记住每次读取的一个字节
//读取一个字节并判断是否读到文件末尾
while((len=in.read())!
=-1){
out.write(len);//将读到的字节写入文件
}
in.close();
out.close();
}
}
需要注意的是,以上例程中在定义文件路径时使用了“\\”,这是因为在Windows路径分隔符基础上添加了转义符(\)。
除此之外,目录符号也可以用正斜线(/)来表示,如:
source/style.mp3。
字节流的缓冲区
实现文件的拷贝时,为了提高效率,可以定义一个字节数组作为缓冲区,然后使用read(byte[]b)方法一次性读取多个字节,并使用write(byte[]b)方法将字符数组中保存的数据一次性写入文件。
装饰设计模式
装饰设计模式就是通过包装一个类,动态地为它增加功能的一种设计模式。
例如,下面的例子实现了RadarCar类对Car类的包装,让Benz车新增了倒车雷达功能。
classCar{
privateStringcarName;//定义一个属性,代表车名
publicCar(StringcarName){
this.carName=carName;
}
publicvoidshow(){//实现Car的show()方法
System.out.println("我是"+carName
+",具有基本功能");
}
}
//定义一个类RadarCar
classRadarCar{
publicCarmyCar;
publicRadarCar(CarmyCar){//通过构造方法接收被包装的对象
this.myCar=myCar;
}
publicvoidshow(){
myCar.show();
System.out.println("具有倒车雷达功能");//实现功能的增强
}
}
字节缓冲流
在IO包中提供两个带缓冲的字节流,分别是BufferedInputStream和BufferdOutputStream,这两个流都使用了装饰设计模式。
它们的构造方法中分别接收InputStream和OutputStream类型的参数作为被包装对象,在读写数据时提供缓冲功能。
应用程序、缓冲流和底层字节流之间的关系如下图所示。
第二课时
(字符流、字符流操作文件、LineNumberReader、转换流)
字符流
✧字符流定义
字符流用来操作字符,字符流也有两个抽象的顶级父类,分别是Reader和Writer。
其中Reader是字符输入流,用于从某个源设备读取字符,Writer是字符输出流,用于向某个目标设备写入字符。
✧Reader和Writer体系结构
Reader体系结构如下图所示:
Writer体系结构如下图所示:
字符流操作文件
✧FileReader和FileWriter
如果想从文件中直接读取字符,可以使用字符输入流FileReader。
FileReader的read()方法可以从关联的文件中读取一个或一组字符。
需要注意的是,字符输入流的read()方法返回的是int类型的值,如果想获得字符就需要进行强制类型转换。
如果要向文件中写入字符就需要使用FileWriter类。
FileWriter是Writer的一个子类,它的用法同FileOutputStream类似。
✧BufferedReader和BufferedWriter
字符流同样提供了带缓冲区的包装流,分别是BufferedReader和BufferedWriter,其中BufferedReader用于对字符输入流进行包装,BufferedWriter用于对字符输出流进行包装。
LineNumberReader
JDK中提供了一个可以跟踪行号的输入流——LineNumberReader,它是BufferedReader的直接子类。
在LineNumberReader类中,定义了跟踪行号的方法,其中setLineNumber()方法用于设置行号的初始值,getLineNumber()方法用于读取行号。
值得注意的是,调用getLineNumber()方法读取行号时,行号是从1开始的。
转换流
为了将字节流转换为字符流,JDK提供了转换流,分别是InputStreamReader和OutputStreamWriter,其中,OutputStreamWriter是Writer的子类,它可以将一个字节流输出流包装成字符输出流,方便直接写入字符,而InputStreamReader是Reader的子类,它可以将一个字节输入流包装成字符输入流,方便直接读取字符。
通过转换流进行数据读写的过程如下图所示。
需要注意的是,在使用转换流时,只能针对操作文本文件的字节流进行转换,如果字节流操作的是一张图片,此时转换为字符流就会造成数据丢失。
第三课时
(ObjectInputStream和ObjectOutputStream、DataInputStream和DatOutputStream、PrintStream、标准输入输出)
ObjectInputStream和ObjectOutputStream
如果希望永久保存对象,则可以将对象转为字节数据写入到硬盘上,这个过程称为对象序列化。
反之,读取被序列化数据的过程称为反序列化。
JDK提供了ObjectInputStream和ObjectInputStream两个类,这两个类分别用于实现对象的序列化和反序列化。
需要注意的是,被序列化的对象必须得实现Serializable接口,否则会出现NotSerializableException异常。
DataInputStream和DataOutputStream
有的时候只需要存储对象的成员数据,而这些成员数据的类型又都是基本数据类型,这时,可以使用IO包中提供的另外两个数据操作流——DataInputStream和DatOutputStream。
DataInputStream和DatOutputStream是两个与平台无关的数据操作流,它们提供了读写各种基本类型数据的方法。
为了保证最终数据的正确性,需要保证读取数据的顺序和写数据的顺序一致。
PrintStream
在Java的IO包中提供了一个PrintStream类,它提供了一系列用于打印数据的print()和println()方法,被称作打印流。
PrintStream可以实现将基本数据类型的数据或引用数据类型的对象格式化成字符串后再输出。
具体示例如下:
PrintStreamps=newPrintStream(
newFileOutputStream("printStream.txt"),true);
ps.print("这是一个数字:
");
ps.println(19);//打印数字
标准输入输出流
在System类中定义了三个常量,这些常量称为标准输入输出流,具体如下:
●in:
标准输入流,InputStream类型,用于读取键盘输入的数据
●out:
标准输出流,PrintStream类型,用于将数据输出到命令行窗口
●err:
标准错误流,PrintStream,用于将应用程序运行时的错误信息输出到控制台
有的时候,程序会向命令行窗口输出大量的数据,由于输出数据滚动的太快,会导致无法阅读,这时可以将标准输出流重新定向到其它的输出设备,重定向流的静态方法如下表所示:
方法声明
功能描述
voidsetIn(InputStreamin)
对标准输入流重定向
voidsetOut(PrintStreamout)
对标准输出流重定向
voidsetErr(PrintStreamout)
对标准错误输出重定向
第四课时
(管道流、ByteArrayOutputStream和ByteArrayInputStream、CharArrayReader和CharArrayWriter、SequenceInputStream)
管道流
在字节流中,管道流分为管道输入流(PipedInputStream)和管道输出流(PipedOutputStream)。
其中,PipedOutputStream用于向管道中写入数据,PipedInputStream用于从管道中读取写入的数据。
同理,字符流中也有一对用于管道通信的管道输入流(PipedReader)和管道输出流(PipedWriter),它们的用法和PipedInputStream、PipedOutputStream相似。
ByteArrayInputStream和ByteArrayOutputStream
ByteArrayOutputStream类会在创建对象时就创建一个byte型数组的缓冲区,当向数组中写数据时,该对象会把所有的数据先写入缓冲区,最后一次性写入文件。
ByteArrayInputStream是从缓冲区中读取数据。
CharArrayReader和CharArrayWriter
CharArrayReader和CharArrayWriter用于将字符型数据临时存入缓冲区,其中,CharArrayReader是从字符数组中读取数据,CharArrayWriter是在内存中创建一个字符数组缓冲区。
SequenceInputStream
SequenceInputStream类可以将几个输入流串联在一起,合并为一个输入流。
当通过这个流来读取数据时,它会依次从所有被串联的输入流中读取数据,对程序来说,就好像是对同一个流进行操作。
使用SequenceInputStream合并两个流的示例代码如下所示:
SequenceInputStreamsis=newSequenceInputStream(in1,in2);
如果想将多个流进行合并,这时需要使用SequenceInputStream类的另一个构造方法,具体如下:
SequenceInputStream(Enumeraion
extendsInputStream>e)
第五课时
(File类、遍历目录下文件、删除文件及目录、RandomAccessFile)
File类
File类用于封装一个路径,这个路径可以是从系统盘符开始的绝对路径,如:
D:
\file\a.txt,也可以是相对于当前目录而言的相对路径,如:
src\Hello.java。
File类内部封装的路径可以指向一个文件,也可以指向一个目录。
创建File对象的构造方法如下表所示:
方法声明
功能描述
File(Stringpathname)
通过指定的一个字符串类型的文件路径来创建一个新的File对象
File(Stringparent,Stringchild)
根据指定的一个字符串类型的父路径和一个字符串类型的子路径(包括文件名称)创建一个File对象
File(Fileparent,Stringchild)
根据指定的File类的父路径和字符串类型的子路径(包括文件名称)创建一个File对象
File类提供了许多方法,用于操作其内部封装路径指向的文件或者目录的方法如下表所示:
方法声明
功能描述
booleanexists()
判断File对象对应的文件或目录是否存在,若存在则返回ture,否则返回false
booleandelete()
删除File对象对应的文件或目录,若成功删除则返回true,否则返回false
booleancreateNewFile()
当File对象对应的文件不存在时,该方法将新建一个此File对象所指定的新文件,若创建成功则返回true,否则返回false
StringgetName()
返回File对象表示的文件或文件夹的名称
StringgetPath()
返回File对象对应的路径
StringgetAbsolutePath()
返回File对象对应的绝对路径(在Unix/Linux等系统上,如果路径是以正斜线(/)开始,则这个路径是绝对路径;在Windows等系统上,如果路径是以从盘符开始,则这个路径是绝对路径)
StringgetParent()
返回File对象对应目录的父目录(即返回的目录不包含最后一级子目录)
booleancanRead()
判断File对象对应的文件或目录是否可读,若可读则返回true,反之返回false
booleancanWrite()
判断File对象对应的文件或目录是否可写,若可写则返回true,反之返回false
booleanisFile()
判断File对象对应的是否是文件(不是目录),若是文件则返回true,反之返回false
booleanisDirectory()
判断File对象对应的是否是目录(不是文件),若是目录则返回true,反之返回false
booleanisAbsolute()
判断File对象对应的文件或目录是否是绝对路径
longlastModified()
返回1970年1月1日0时0分0秒到文件最后修改时间的毫秒值;
longlength()
返回文件内容的长度
String[]list()
列出指定目录的全部内容,只是列出了名称
File[]listFiles()
返回一个包含了File对象所有子文件和子目录的File数组
File遍历目录下的文件
在File类中,重载的list()方法用于遍历指定目录文件,如果在遍历过程中,需要获取指定类型的文件,则可以使用list(FilenameFilterfilter)方法,其中,参数FilenameFilter是一个接口,称作文件过滤器,使用list(FilenameFilterfilter)方法遍历目录文件的步骤如下所示:
1、调用list()方法传入FilenameFilter文件过滤器对象
2、取出当前File对象所代表目录下的所有子目录和文件
3、对于每一个子目录或文件,都会调用文件过滤器对象的accept(Filedir,Stringname)方法,并把代表当前目录的File对象以及这个子目录或文件的名字作为参数dir和name传递给方法
4、如果accept()方法返回true,就将当前遍历的这个子目录或文件添加到数组中,如果返回false,则不添加。
删除文件及目录
在File类中,delete()方法只能删除指定的文件,如果希望删除某个目录,则需要通过递归的方式将整个目录以及其中的文件全部删除。
实现递归的代码如下所示:
publicstaticvoiddeleteDir(Filedir){
if(dir.exists()){//判断传入的File对象是否存在
File[]files=dir.listFiles();//得到File数组
for(Filefile:
files){//遍历所有的子目录和文件
if(file.isDirectory()){
//如果是目录,递归调用deleteDir()
deleteDir(file);
}else{
//如果是文件,直接删除
file.delete();
}
}
//删除完一个目录里的所有文件后,就删除这个目录
dir.delete();
}
}
RandomAccessFile
在IO包中,提供了一个类RandomAccesseFile,RandomAccesseFile不属于流类,但它具有读写文件数据的功能,可以随机地从文件的任何位置开始执行读写数据的操作。
RandomAccessFile可以将文件以只读或者读写的方式打开,具体使用哪种方式取决于创建它所采用的构造方法,RandomAccessFile的构造方法如下表所示:
方法声明
功能描述
RandomAccessFile(Filefile,Stringmode)
参数file指定被访问的文件
RandomAccessFile(Stringname,Stringmode)
参数name指定被访问文件的路径
RandomAccessFile类针对文件的随机访问操作,提供了一些用于定位文件位置的方法定位文件位置的方法,如下表所示:
方法声明
功能描述
longgetFilePointer()
返回当前读写指针所处的位置
voidseek(longpos)
设定读写指针的位置,与文件开头相隔pos个字节数
intskipBytes(intn)
使读写指针从当前位置开始,跳过n个字节
voidsetLength(longnewLength)
设置此文件的长度
第六课时
(常用字符集、字符编码和解码)
常用字符集
字符码表是一种可以方便计算机识别的特定字符集,它是将每一个字符和一个唯一的数字对应而形成的一张表,下面就来介绍几种最常用的字符码表,如下表所示。
ASCII
美国标准信息交换码,使用7位二进制数来表示所有的大小写字母
数字0到9、标点符号、以及在美式英语中使用的特殊控制字符
ISO8859-1
拉丁码表,兼容ASCII,还包括了西欧语言、希腊语、泰语、阿拉伯语等
GB2312
中文码表,兼容ASCII,每个英文占1个字节,中文占2个字节(两个字节都为负数,最高位都为1)
GBK、GB18030
兼容GB2312,包含更多中文,每个英文占一个字节,中文占2个字节(第1个字节为负数,第2个字节可正可负)
Unicode
国际标准码,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求,每个字符占2个字节。
Java中存储的字符类型就是使用Unicode编码
UTF-8
是针对Unicode的可变长编码,可以用来表示Unicode标准中的任何字符,其中,英文占1个字节,中文占3个字节,这是程序开发中最常用的字符码表
字符编码和解码
一般来说,把字符串转换成计算机识别的字节序列称为编码,而把字节序列转换为普通人能看懂的明文字符串称为解码,如下表所示:
第七课时
上机练习1(总结,测试题)
1、总结本章内容
2、通过题库发放相关测试题,检查学生掌握情况。
3、上机练习:
针对本章中需要重点掌握的知识点,以及在程序中容易出错的内容进行练习,通过上机练习可以考察同学对知识
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第8章 IO输入输出教学设计 IO 输入输出 教学 设计