java第6章 io流PPT学习课件_第1页
java第6章 io流PPT学习课件_第2页
java第6章 io流PPT学习课件_第3页
java第6章 io流PPT学习课件_第4页
java第6章 io流PPT学习课件_第5页
已阅读5页,还剩94页未读 继续免费阅读

下载本文档

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

文档简介

第6章I/O:读和写,1,课前思考,如何读取硬盘上的某个文件内容?如何知道文件系统中有哪些目录和子目录?如何往硬盘上写文件?如何接收键盘输入?,2,教学目标,与外部设备和其它计算机进行交流的输入输出操作,尤其是对磁盘的文件操作,是计算机程序重要的功能,任何计算机语言都必须对输入输出提供支持。Java也不例外,它的输入输出类库中包含了丰富的系统工具,这些类被放在java.io包中。在该类库中,除了定义文件输入输出操作外,还定义了许多用来和其他外设进行信息交换的类。本章将详细介绍I/O类库中的基本内容,主要侧重于文件的输入输出管理和流的基本概念。,3,流,在计算机中,“流”的概念是1984年由C语言第一次引入的。“流”可以看作是一个流动的数据缓冲区,数据从数据源流向数据目的地。,4,I/O与流,I/O是程序设计中的重要问题,大部分的应用程序都需要I/O操作,比如从键盘获得用户输入、在屏幕输出运行结果、对磁盘文件进行读写等等。应用程序只有通过I/O操作才能实现与用户的交互及数据的处理及存储.在Java语言中,将不同类型的I/O抽象为流。所谓“流(stream)”,可以看作是数据在文件或程序之间的传递,5,输入流和输出流,一般来说,流有两种基本形式:输入流和输出流,根据程序是作为数据流的目的端还是源端来划分。程序首先要打开一个流,才能与数据文件进行通信。通过输入流,程序可以从数据文件读取数据,但不可向输入流中写入数据;反之,通过输出流,程序可以向数据文件中写入数据。程序与其他设备间的I/O也可以使用流,这时可将设备看作是一个数据文件。,6,JavaI/O流类的组织模式,7,java.io,在Java开发环境中,主要是由包java.io中提供的一系列的类和接口来实现输入/输出处理。而标准输入/输出处理则是由包java.lang中提供的类来处理的,这些类又都是从包java.io中的类继承而来的。I/O类提供了低层次和高层次的界面。每一种介质都有一对与之相关联的输入输出类,它们提供低层次的面向数据序列(字符、字节)的界面。与介质相关的各个类都分别是输入输出抽象流类的子类,它们通常具有与介质相关的构造器及方法。I/O抽象类为所有与介质相关的具体输入输出类提供了一个统一的界面。反过来各个具体的与介质相关的输入输出类也扩展了抽象类,通过它们可以实现在具体介质上的输入输出操作,8,I/O操作的一般步骤,构造一个与介质相关的I/O对象,以提供一种低层次的方法将数据输入或输出到相应的介质;将与介质相关的对象强制类型转换为它的父类(即抽象I/O类),并利用该对象构造一个流对象。这样便建立起了流类对象与介质相关对象的关联;这时就可利用流对象的I/O方法进行相应介质上的数据读写。,9,字节流与字符流,从流中传输的数据单位分为两类:字节流从InputStream和OutputStream派生出来的一系列类,以字节(byte)为基本处理单位。字符流从Reader和Writer派生出的一系列类,以16位的Unicode码表示的字符为基本处理单位。,10,字节流,11,InputStream类,InputStream类定义了一套所有字节输入流所需的方法,12,OutputStream类,OutputStream类定义了一套所有字节输出流所需的方法。,13,字符流类,14,Reader与Writer类,Reader类的相关方法:voidclose()voidmark(intreadAheadLimit)booleanmarkSupported()intread()intread(charcbuf)intread(charcbuf,intoff,intlen)booleanready()voidreset()longskip(longn)Writer类的相关方法:voidclose()voidflush()voidwrite(charcbuf)voidwrite(charcbuf,intoff,intlen)voidwrite(intc)voidwrite(Stringstr)voidwrite(Stringstr,intoff,intlen),15,各种流的作用概述,16,各种流的作用概述,17,各种流的作用概述,18,各种流的作用概述,19,文件流,要对本机文件系统上的文件进行读写,需要使用文件流。Java的文件流类包括字符流的FileReader、FileWriter和字节流的FileInputStream、FileOutputStream。,20,Java中文件的操作,而要进行文件流操作,首先必须清楚java中关于文件的基本操作,下面我们进行详细介绍。,21,文件与目录的描述类FileFile类并不用来进行文件的读/写操作,它用来描述文件对象的属性,既可以表示文件,也可以表示目录。使用它提供的方法,我们可以得到所指对象的描述信息,包括名称、存在否、读/写权限、路径等等。,22,需要注意的是,当我们在Windows环境使用路径时,其分隔符不能是单一的“”符号,因为与C/C+相同,符号“”已经被转意了。例如:c:jbuilder3javabin路径是非法的,系统不会识别,正确的应该为c:jbilder3javabin或者直接使用反斜杠/来作为路径分隔符。如c:/jbilder3/java/bin,23,文件描述,类File提供了一种与机器无关的方式来描述一个文件对象的属性。文件的生成publicFile(Stringpath);publicFile(Stringpath,Stringname);publicFile(Filedir,Stringname);,24,文件描述,文件名的处理StringgetName();/*得到一个文件的名称(不包括路径)*/StringgetPath();/得到一个文件的路径名StringgetAbsolutePath();/*得到一个文件的绝对路径名*/StringgetParent();/*得到一个文件的上一级目录名*/StringrenameTo(FilenewName);/*将当前文件名更名为给定文件的完整路径*/,25,文件描述,文件属性测试booleanexists();/*测试当前File对象所指示的文件是否存在*/booleancanWrite();/测试当前文件是否可写booleancanRead();/测试当前文件是否可读booleanisFile();/*测试当前文件是否是文件(不是目录)*/booleanisDirectory();/*测试当前文件是否是目录*/,26,文件描述,普通文件信息和工具longlastModified();/*得到文件最近一次修改的时间*/longlength();/得到文件的长度,以字节为单位booleandelete();/删除当前文件目录操作booleanmkdir();/*根据当前对象生成一个由该对象指定的路径*/Stringlist();/列出当前目录下的文件,27,File类的方法及变量,28,29,30,下面我们给出几个File类的应用实例。通过例题的使用,希望对File类有更清楚的认识。例importjava.io.*;publicclassMyClass1publicstaticvoidmain(Stringargs)Filef=newFile(c:jbuilder3myprojectsuntitled5MyClass1.java);if(!f.exists(),31,System.out.println(FileMyClass1.javadoesntexist!);elseSystem.out.println(Thisfilecanread+f.canRead();System.out.println(lastmodified+f.lastModified();System.out.println(Parentis+f.getParent();System.out.println(Filelengthis+f.length();publicMyClass1(),32,图7.3,33,例importjava.io.*;classFileTestpublicstaticvoidmain(Stringargs)System.out.println(pathseparator+File.pathSeparator);System.out.println(pathseparatorchar+File.pathSeparatorChar);System.out.println(separator+File.separator);System.out.println(separatorchar+File.separatorChar);Filef=newFile(/dong1/test1.class);System.out.println();System.out.println(f);System.out.println(exist?+f.exists();,34,System.out.println(name+f.getName();System.out.println(path+f.getPath();System.out.println(absolutepath+f.getAbsolutePath();System.out.println(parent+f.getParent();System.out.println(isafile?+f.isFile();System.out.println(isadirectory?+f.isDirectory();System.out.println(length+f.length();System.out.println(canread+f.canRead();System.out.println(canwrite+f.canWrite();System.out.println(lastmodified+f.lastModified();,35,FilenewF=newFile(newFile);System.out.println(.Rename+f+.);f.renameTo(newF);System.out.println(name+newF.getName();System.out.println(f+exist?+f.exists();System.out.println(.delete+newF+.);newF.delete();System.out.println(newF+exist?+newF.exists();,36,运行结果,pathseparator:pathseparatorchar:separator/separatorchar/dong1/test1.classexist?truenametest1.classpath/dong1/test1.classabsolutepath/dong1/test1.classparent/dong1,37,运行结果,isafile?trueisadirectory?falselength514canreadtruecanwritetruelastmodified907117020000.Rename/dong1/test1.classnamenewFile/dong1/test1.classexist?false.deletenewFile.newFileexist?false,38,文件夹处理,list方法用于列出一个目录中所有的文件或与某个模式相匹配的文件。列出目录中与某种模式相匹配的文件:publicStringlist(FilenameFilterfilter);在接口FilenameFilter中定义的方法只有:booleanaccept(Filedir,Stringname);,39,例:importjava.io.*;publicclassFileFilterTestpublicstaticvoidmain(Stringargs)Filedir=newFile(“/dongl”);Filterfilter=newFilter(“htm”);System.out.println(“listhtmlfilesindirectory”+dir);Stringfiles=dir.list(filter);,40,for(inti=0;ifiles.length;i+)Filef=newFile(filesi);if(f.isFile()System.out.println(“file”+f);elseSystem.out.println(“subdirectory”+f);,41,classFilterimplementsFilenameFilterStringextent;Filter(Stringextent)this.extent=extent;publicbooleanaccept(Filedir,Stringname)returnname.endsWith(“.”+extent);,42,运行结果,listhtmlfilesindirectoty/donglfilecert_test.htmfilecert_sample.htmfilecert_obj.htm,43,例importjava.io.*;publicclassMyClass2publicstaticvoidmain(Stringargs)Filef1=newFile(c:jbuilder3myprojects);if(!f1.isDirectory()System.out.println(Error:+f1+isntadirectory!);elseStringdirList=f1.list();for(inti=0;idirList.length;i+)System.out.println(dirListi);publicMyClass2(),44,在该例中,我们并没有在调用File类的list方法中传递参数,这样,处在目录c:jbuilder3myprojects下的所有文件及目录将均被输出,结果如图7.4所示。,45,图7.4,46,1Byte流(字节流)文件的读取该类的结构如图7.1所示,我们主要用其中的FileOutputStream和FileInputStream类,它们的父类为InputStream和OutputStream。主要的方法有:InputStreamintread()intread(bytebuf)intread(bytebuf,intoffset,intlength)close(),利用流进行文件I/O处理,47,OutputStreamintwrite(intc)intwrite(bytebuf)intwrite(bytebuf,intoffset,intlength)close()下面给出一个应用实例7.4。,48,图7.5,49,例7.4importjava.io.*;publicclassFileCopypublicstaticvoidmain(Stringargs)throwsIOExceptionFileInputStreamf1;FileOutputStreamf2;f1=newFileInputStream(FileCopy.java);f2=newFileOutputStream(acopy_of_java_file);,50,inttemp;while(temp=f1.read()!=-1)f2.write(temp);f1.close();f1.close();publicFileCopy()在该例中,我们利用字节流将本程序拷贝至另一个文件acopy_of_java_file中,如果指定的文件不存在,则创建一个新文件,否则原文件的内容会被新写入的内容覆盖。当程序运行后,将生成一个与原程序相同的副本。,51,2Character流(字符流)文件的读取该类如图7.2所示,输入/输出类的父类为Reader、Writer,其基本的方法有:Readerintread()intread(charbuf)intread(charbuf,intoffset,intlength)close(),52,Writerintwrite(intc)intwrite(charbuf)intwrite(charbuf,intoffset,intlength)close()读者可与字节流进行比较,注意二者方法的区别。下面我们用字符流来改写例7.4:,53,例7.5importjava.io.*;publicclassFileCopypublicstaticvoidmain(Stringargs)throwsIOExceptionFileReaderf1;FileWriterf2;f1=newFileReader(FileCopy.java);f2=newFileWriter(acopy_of_java_file);,54,inttemp;while(temp=f1.read()!=-1)f2.write(temp);f1.close();f2.close();publicFileCopy(),55,例7.6importjava.io.*;publicclassReadFilepublicstaticvoidmain(Stringargs)throwsIOExceptionFileReaderfr=newFileReader(ReadFile.java);BufferedReaderbr=newBufferedReader(fr);Stringline=br.readLine();while(line!=null),56,System.out.println(line);line=br.readLine();br.close();本程序中,我们通过类BufferedReader对文件实现按行读取,达到一行一行输出的目的,结果如图7.6所示。,57,图7.6,58,3二进制数据流的文件读取如果要读取与机器无关的基本数据类型的数据,如整型或浮点型的二进制数,就要用到二进制数据文件流DataInputStream、DataOutputStream。实际使用中,类DataInputStream和DataOutputStream必须和一个输入类(InputStream)或输出类(OutputStream)联接起来,不能直接用文件名或文件对象(File)对其直接初始化,例如:,59,例7.7importjava.io.*;publicclassDatastreamDemopublicstaticvoidmain(Stringargs)throwsIOExceptionFileOutputStreamf2=newFileOutputStream(data);DataOutputStreamdfo=newDataOutputStream(f2);dfo.writeBoolean(true);,60,dfo.writeInt(100);dfo.writeFloat(200.2f);f2.close();dfo.close();FileInputStreamf1=newFileInputStream(data);DataInputStreamdfi=newDataInputStream(f1);booleanb=dfi.readBoolean();inti=dfi.readInt();floatf=dfi.readFloat();f1.close();dfi.close();System.out.println(Thevalueis:);,61,System.out.println(+b);System.out.println(+i);System.out.println(+f);publicDatastreamDemo(),该例中,我们首先利用类DataOutputStream生成一个二进制文件data,并对它写入三个不同类型的数据:布尔型、整型、浮点型。然后利用DataInputStream读入刚刚输入的数据并显示出来,结果如图7.7所示。可以看出,输出结果与我们的输入是一一对应的。,62,图7.7,63,4随机访问文件的读取对于InputStream/OutputStream、Reader/Writer类来说,它们都是顺序访问流,只能进行顺序读写。而所谓随机读写,是指读写完上一个字节后,不只能读写其后继的字节,还可以读写文件中任意的字节,就好象文件中有一个随意移动的指针一样。Java语言提供了类RandomAccessFile来进行随机文件的读取。在生成一个RandomAccessFile对象时,不仅要说明文件对象或文件名,同时还需指明访问模式,即“只读方式”(r)或“读写方式”(rw),这类似于C/C+中的fopen()函数。,64,随机文件处理,使用流的形式对文件进行读写必须顺序进行,也就是说这些文件流的数据必须按先后次序进行处理。在对某些顺序存储访问介质,例如磁带等进行访问时,这样的文件流方式非常有用随机文件存取提供了一种更灵活的文件读写方式,它允许对文件的内容进行非顺序的访问。在这里,“随机”是指所存取的数据不需要与以前存取过的历史数据有任何的关系。使用随即文件存取方式可以在打开一个文件后同时进行读写操作,并且可以移动文件指针使其指向文件中的任何位置,65,随机存取文件的结构,在文件内部,文件被分成固定长度的数据块(记录)。从概念上来说,文件可以看作是一个记录数组。文件指针的移动是以记录为单位的。,66,RandomAccessFile类,RandomAccessFile类的构造函数使用了两个参数,第一个参数表示要操作的文件,可以使用字符串类型的文件名也可以使用一个文件对象;第二个字符串类型的参数mode表示了对文件的操作方式:mode为”r”时表示可以从文件读取;mode为”rw”时表示既可以从文件读取也可以向文件写入RandomAccessFile类通过实现DataInput和DataOutPut的方法来实现文件数据的读写,这些方法允许使用二进制编码形式将基本的Java类型写入或读出文件。在RandomAccessFile类中还提供了一些操作文件指针的方法,如通过seek方法可以将文件指针移动到其参数所制定的位置。,67,RandomAccessFile类的功能类似于DataOutputStream类和DataInputStream类的功能合并,即实现了在一个流中进行读、写两种功能。其常用的方法如表7.2所示。,68,表7.2RandomAccessFile类的常用方法,69,例程,importjava.io.*;publicclassFileTestpublicstaticvoidmain(Stringargs)throwsIOExceptionRandomAccessFileraf=newRandomAccessFile(foo.txt,rw);tryWriterout=newOutputStreamWriter(newFileOutputStream(raf.getFD(),UTF-8);out.write(HelloWorld!);out.flush();raf.seek(6);out.write(Java);out.flush();finallyraf.close();,70,例7.8的功能与例7.7一样,只不过是用RandomAccessFile来实现的。例7.8importjava.io.*;publicclassRandomDemopublicstaticvoidmain(Stringargs)throwsIOExceptionRandomAccessFilefa=newRandomAccessFile(data,rw);,71,fa.writeBoolean(true);fa.writeInt(100);fa.writeFloat(200.2f);fa.seek(0);booleanb=fa.readBoolean();inti=fa.readInt();floatf=fa.readFloat();System.out.println(Thevaluereadfromarandomfileis:);System.out.println(+b);System.out.println(+i);System.out.println(+f);,72,fa.close();publicRandomDemo()程序运行结果如图7.8所示。,73,图7.8,74,例程,importjava.io.*;classCopyprivatevoidcopy(InputStreamin,OutputStreamout)throwsIOExceptionbytebuf=newbyte4096;intlen=in.read(buf);while(len!=-1)out.write(buf,0,len);len=in.read(buf);publicvoidcat(Stringfsrc,Stringfdest)tryInputStreamin=newFileInputStream(fsrc);OutputStreamout=newFileOutputStream(fdest,true);copy(in,out);out.close();in.close();catch(IOExceptionex)System.err.println(ex);,75,例程-cont.,publicclassUseCopypublicstaticvoidmain(Stringargs)Copyc=newCopy();c.cat(“in.dat”,”out.dat”);,76,7.3.2内存的I/O流表7.3给出了Java支持内存读/写的类,总结起来有以下两类。(1)对应字节内存读/写的有ByteArrayInputStream、ByteArrayOutputStream及StringBufferInputStream。它们可以从字节数组中读取数据或向字节数组中写入数据。例如:例7.10importjava.io.*;publicclassMemoryDemo,77,publicstaticvoidmain(Stringargs)throwsIOExceptionbyteb=111,100,74,98,80,69;bytetemp=newbyte10;ByteArrayInputStreambi=newByteArrayInputStream(b);ByteArrayOutputStreambo=newByteArrayOutputStream();StringBufferInputStreambs=newStringBufferInputStream(Ademoformemoryinput!);intx;while(x=bi.read()!=-1),78,bo.write(x);System.out.println(TheresultofByteArrayOutputStreamis:+bo);bs.read(temp,0,4);System.out.print(TheresultofStringBufferOutputStreamis:);for(inti=0;i=3;i+)System.out.print(+tempi);System.out.println();System.out.print(+bs);运行结果如图7.9所示。,79,图7.9,80,对于ByteArrayOutputStream来说,我们先从ByteArrayInputStream类中把字节流读入bo的缓冲区中,然后直接进行输出,该对象调用自己的toString()进行输出格式转换。(2)对应字符内存读/写的有CharArrayReader、CharArrayWriter、StringReader及StringWriter。它们可以从字符数组中读取数据或向字符数组中写入数据。例如:例7.11importjava.io.*;publicclassMemoryDemo,81,publicstaticvoidmain(Stringargs)throwsIOExceptioncharb=a,t,e,s,t,d,e,m,o;chartemp=newchar10;CharArrayReaderbr=newCharArrayReader(b);CharArrayWriterbw=newCharArrayWriter();StringReaderbsr=newStringReader(testdemo!);StringWriterbsw=newStringWriter();intx;while(x=br.read()!=-1)bw.write(x);,82,System.out.println(TheresultofCharArrayReaderis:+bw);bsr.read(temp,0,4);System.out.print(TheresultofStringReaderis:);for(inti=0;i=3;i+)System.out.print(+tempi);System.out.println();bsw.write(hello,everybody!);System.out.print(TheresultofStringWriteris:);System.out.println(+bsw);程序运行结果如图7.10所示。,83,图7.10,84,我们可以发现以上两个程序的基本架构无大的区别,只是对不同内存流,构造方法有所不同。上述的几种输出内存流,它们在初始化的时候,缺省的缓冲区的大小均为32个字节。当然,实际操作过程中,缓冲区的大小会随数据的写入自动增加。不同的类会有多种不同的方法,方法的使用建立在对各种流的熟悉程度之上,读者应尽可能的学习Java联机文档的内容,获取更多的知识。,85,内存流,为了支持内存上的输入输出,java.io包内提供了一组相关的类:字节流类ByteArrayInputStreamByteArrayOutputStreamStringBufferInputStream字符流类CharArrayReaderCharArrayWriterStringReaderStringWriter,86,例程,importjava.io.*;publicclassByteArrayOutputStreamTestpublicstaticvoidmain(Stringargs)tryByteArrayOutputStreambaos=newByteArrayOutputStream();PrintStreamps=newPrintStream(baos);for(inti=0;i1000;i+)ps.println(i+ABCDEFGHIJKLMNOPQRSTUVWXYZ);longstart=System.currentTimeMillis();FileOutputStreamfos=newFileOutputStream(ByteArrayOutputStreamTest);baos.writeTo(fos);fos.close();longstop=System.currentTimeMillis();System.out.println(timeelapsed(milliseconds)=+(stop-start);catch(FileNotFoundExceptionfnfe)System.out.println(fnfe.getMessage();catch(IOExceptionioe)System.out.println(ioe.getMessage();,87,7.3.1管道流管道流(PipedStream)可用来把一个程序、线程或代码段的输出直接连接到另一个程序、线程或代码段的输入。Java中管道的类有PipedReader、PipedWriter、PipedInputStream及PipedOutputStream。,88,管道流,使用过程中,管道输入流作为一个通信管道的接收端,进行数据的读取,管道输出流则作为发送端,进行数据的传送。管道流必须是输入输出并用,也就是说在使用管道前,两者必须进行连接。,89,为什么要用到管道流?,当某个程序的输出作为另外一个程序的输入时,如果没有管道,就必须为程序提供一个存放中间结果的位置,前一个程序将输出数据写入该位置,而后一个程序再从该位置读出这些数据,这样的做法无疑是低效率的。通过管道,可以连接程序的输出和输入,直接将前一程序的输出作为后一程序的输入,提高了程序效率。,90,管道流的连接方式,java.io中为字符类型和字节类型各提供了一对输入输出管道流类:PipedReader/PipedWriter和PipedInputStream/PipedOutputStream。管道流的连接方式有两种,以PipedInputStream/PipedOutputStream为例:在构造方法中进行连接:PipedInputStream(Pipe

温馨提示

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

评论

0/150

提交评论