1第六章输入/输出流和文件6.1输入/输出流6.2文件读写26.1输入/输出流通常程序需要从外部获取/输出信息这个“外部”范围很广,包括诸如键盘、显示器、文件、磁盘、网络、另外一个程序等“信息”也可以是任何类型的,例如一个对象、串字符、图像、声音等通过使用java.io包中的输入/输出流类就可以达到输入输出信息的目的36.1.1I/O流的概念流:数据从计算机的输入向输出流动,即流的产生。流有两种:文本流(字符)和二进制流(字节)在Java里,流是一些类。在Java中将信息的输入与输出过程抽象为I/O流输入是指数据流入程序输出是指数据从程序流出一个流就是一个从源流向目的地的数据序列46.1.1I/O流的概念文件File也是一个逻辑概念。计算机的所有设备都可理解为一个文件。流可与文件建立联系。java.lang.Objectjava.io.Filejava.io.RandomAccessFilejava.io.InputStreamjava.io.OutputStreamjava.io.Readerjava.io.WriterIO流类一旦被创建就会自动打开通过调用close方法,可以显式关闭任何一个流;如果流对象不再被引用,Java的垃圾回收机制也会隐式地关闭它56.1.1I/O流的概念输入流为了从信息源获取信息,程序打开一个输入流,程序可从输入流读取信息输出流当程序需要向目标位置写信息时,便需要打开一个输出流,程序通过输出流向这个目标位置写信息66.1.1I/O流的概念源和目标的类型对象源?目标?或两者?diskfilerunningprogrammonitorkeyboardInternetconnectionimagescannermouseBothBothDestinationSourceBothSourceSource76.1.1I/O流的概念读写数据的方法不论数据从哪来,到哪去,也不论数据本身是何类型,读写数据的方法大体上都是一样的:打开一个流,读/写信息,关闭流。86.1.2预定义的I/O流类概述输入/输出流可以从以下几个方面进行分类从流的方向划分输入流输出流从流的分工划分节点流处理流从流的内容划分面向字符的流面向字节的流96.1.2预定义的I/O流类概述java.io包的顶级层次结构面向字符的流:专门用于字符数据面向字节的流:用于一般目的106.1.2预定义的I/O流类概述面向字符的流针对字符数据的特点进行过优化,提供一些面向字符的有用特性源或目标通常是文本文件实现内部格式和文本文件中的外部格式之间转换内部格式:16-bitchar数据类型外部格式:UTF(UniversalcharactersetTransformationFormat):很多人称之为UniversalTextFormat包括ASCII码及非ASCII码字符,比如:斯拉夫(Cyrillic)字符,希腊字符,亚洲字符等116.1.2预定义的I/O流类概述面向字符的抽象类——Reader和Writerjava.io包中所有字符流的抽象基类Reader提供了输入字符的APIWriter提供了输出字符的API它们的子类又可分为两大类节点流:从数据源读入数据或往目的地写出数据处理流:对数据执行某种处理多数程序使用这两个抽象类的一系列子类来读入/写出文本信息例如FileReader/FileWriter用来读/写文本文件12阴影部分为节点流136.1.2预定义的I/O流类概述面向字节的流数据源或目标中含有非字符数据,必须用字节流来输入/输出通常被用来读写诸如图片、声音之类的二进制数据绝大多数数据是被存储为二进制文件的,世界上的文本文件大约只能占到2%,通常二进制文件要比含有相同数据量的文本文件小得多。146.1.2预定义的I/O流类概述面向字节的流InputStream和OutputStream是用来处理8位字节流的抽象基类,程序使用这两个类的子类来读写8位的字节信息分为两部分节点流处理流156.1.2预定义的I/O流类概述面向字节的流阴影部分为节点流166.1.2预定义的I/O流类概述标准输入输出标准输入输出流属于System类。System类实现了用户使用资源时的系统无关编程接口;是final类;所有变量和方法都是static的;不用初始化(new)就可以使用System类的静态成员变量System.in:InputStream类型的,代表标准输入流,这个流是已经打开了的,默认状态对应于键盘输入。System.out:PrintStream类型的,代表标准输出流,默认状态对应于屏幕输出System.err:PrintStream类型的,代表标准错误信息输出流,默认状态对应于屏幕输出176.1.2预定义的I/O流类概述标准输入输出System.inpublicfinalstaticInputStreamin=newInputStream();read(),read(byteb[],intoff,intlen),read(byteb[])System.outpublicfinalstaticPrintStreamout=newPrintStream();print(),println(),write()System.errpublicfinalstaticPrintStreamerr=newPrintStream();print(),println(),write()186.1.2预定义的I/O流类概述从键盘读入信息并在显示器上显示importjava.io.*;publicclassEcho{publicstaticvoidmain(String[]args)throwsIOException{BufferedReaderin=newBufferedReader(newInputStreamReader(System.in));Strings;while((s=in.readLine()).length()!=0)System.out.println(s);}}运行结果Hello!Hello!196.1.2预定义的I/O流类概述System.in程序启动时由Java系统自动创建的流对象,它是原始的字节流,不能直接从中读取字符,需要对其进行进一步的处理InputStreamReader(System.in)以System.in为参数创建一个InputStreamReader流对象,相当于字节流和字符流之间的一座桥梁,读取字节并将其转换为字符BufferedReaderin对InputStreamReader处理后的信息进行缓冲,以提高效率206.1.2预定义的I/O流类概述一个方便的扫描API:把文本转化成基本类型或者StringScanners=newScanner(System.in);intn=s.nextInt();还有下列方法:nextByte(),nextDouble(),nextFloat,nextInt(),nextLine(),nextLong(),nextShort()216.1.2预定义的I/O流类概述处理流不直接与数据源或目标相连,而是基于另一个流来构造从流读写数据的同时对数据进行处理InputStreamReader和BufferedReader都属于处理流InputStreamReader读取字节并转换为字符BufferedReader对另一个流产生的数据进行缓冲用一行表达式实现:BufferedReaderstdin=newBufferedReader(newnputStreamReader(System.in));226.1.2预定义的I/O流类概述I/O异常多数IO方法在遇到错误时会抛出异常,因此调用这些方法时必须在方法头声明抛出IOException异常或者在try块中执行IO,然后捕获IOException23第六章输入/输出流和文件6.1输入/输出流6.2文件读写写文本文件读文本文件写二进制文件读二进制文件File类对象序列化随机文件读写246.2.1写文本文件FileWriter类创建一个磁盘文件关闭一个磁盘文件write()方法捕获I/O异常BufferedWriter类256.2.1写文本文件在C盘根目录创建文本文件Hello.txt,并往里写入若干行文本importjava.io.*;classWriteTxtFile{publicstaticvoidmain(String[]args)throwsIOException{//main方法中声明抛出IO异常StringfileName=“C:\Hello.txt;FileWriterwriter=newFileWriter(fileName);writer.write(Hello!\n);writer.write(Thisismyfirsttextfile,\n);writer.write(Youcanseehowthisisdone.\n);writer.write(输入一行中文也可以\n);writer.close();}}266.2.1写文本文件打开C盘根目录下的Hello.txt文件每次运行这个程序,都将删除已经存在的”Hello.txt”文件,创建一个新的同名文件FileWriter的构造方法有五个,本例是通过一个字符串指定文件名来创建FileWriter类的write方法向文件中写入字符换行有些问题276.2.1写文本文件上例WriteTxtFile说明Writer类的流可实现内部格式到外部磁盘文件格式转换“Hello.txt”是一个普通的ASCII码文本文件,每个英文字符占一个字节,中文字符占两个字节Java程序中的字符串则是每个字符占两个字节的,采用Unicode编码close方法清空流里的内容并关闭它。如果不调用该方法,可能系统还没有完成所有数据的写操作,程序就结束了286.2.1写文本文件处理IO异常importjava.io.*;classWriteTxtFile2{publicstaticvoidmain(String[]args){StringfileName=c:\\Hello.txt;try{//将所有IO操作放入try块中FileWriterwriter=newFileWriter(fileName,true);writer.write(Hello!\n);writer.write(Thisismyfirsttextfile,\n);writer.write(Youcanseehowthisisdone.\n);writer.write(输入一行中文也可以\n);writer.close();}catch(IOExceptioniox){System.out.println(Problemwriting+fileName);}}}296.2.1写文本文件运行此程序,会发现在原文件内容后面又追加了重复的内容,这就是将构造方法的第二个参数设为true的效果如果将文件属性改为只读属性,再运行本程序,就会出现IO错误,程序将转入catch块中,给出出错信息306.2.1写文本文件BufferedWriter类如果需要写入的内容很多,就应该使用更为高效的缓冲器流类BufferedWriterFileWriter和BufferedWriter类都用于输出字符流,包含的方法几乎完全一样,但BufferedWriter多提供了一个newLine()方法用于换行不同厂家生产的计算机(IBM,Apple,VAX,Sun)对文字的换行方法不同。newLine()方法可以输出在当前计算机上正确的换行符316.2.1写文本文件使用BufferedWriter完成例WriteTxtFi