版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
JavaJavaI/O系统对编程语言的设计者来说,创建一套好的输入输出(I/O)系统,是一项难度极高的任务。这一点可以从解决方案的数量之多上看出端倪。这个问题难就难在它要面对的可能性太多了。不仅是因为有那么多I/O的源和目地(文件,控制台,网络连接等等),而且还有很多方法(顺序的『sequential』,随机的『random-access』,缓存的『buffered』,二进制的『binary』,字符方式的『character』,行的『bylines』,字的『bywords』,等等)。Java类库的设计者们用"创建很多类"的办法来解决这个问题。坦率地说JavaI/O系统的类实在是太多了,以至于初看起来会把人吓着(但是,具有讽刺意味的是,这种设计实际上是限制了类的爆炸性增长)。此外,Java在1.0版之后又对其I/O类库作了重大的修改,原先是面向byte的,现在又补充了面向Unicode字符的类库。为了提高性能,完善功能,JDK1.4又加了一个nio(意思是"newI/O"。这个名字会用上很多年)。这么以来,如果你想对Java的I/O类库有个全面了解,并且做到运用自如,你就得先学习大量的类。此外,了解I/O类库的演化的历史也是相当重要的。可能你的第一反应是"别拿什么历史来烦我了,告诉我怎么用就可以了!"但问题是,如果你对这段历史一无所知,很快就会被一些有用或是没用的类给搞糊涂了。本章会介绍Java标准类库中的各种I/O类,及其使用方法。File类在介绍直接从流里读写数据的类之前,我们先介绍一下处理文件和目录的类。File类有一个极具欺骗性的名字;或许你会认为这是一个关于文件的类,但它不是。你可以用它来表示某个文件的名字,也可以用它来表示目录里一组文件的名字。如果它表示的是一组文件,那么你还可以用list()方法来进行查询,让它会返回String数组。由于元素数量是固定的,因此数组会比容器更好一些。如果你想要获取另一个目录的清单,再建一个File对象就是了。实际上,叫它"FilePath"可能会更好一些。下面我们举例说明怎样使用这个类及其相关的FilenameFilter接口。目录列表器假设你想看看这个目录。有两个办法。一是不带参数调用list()。它返回的是File对象所含内容的完整清单。但是,如果你要的是一个"限制性列表(restrictedlist)"的话——比方说,你想看看所有扩展名为.java的文件——那么你就得使用"目录过滤器"了。这是一个专门负责挑选显示File对象的内容的类。下面就是源代码。看看,用了java.utils.Arrays.sort()和11章的AlphabeticComparator之后,我们没费吹灰之力就对结果作了排序(按字母顺序)://:c12:DirList.java//Displaysdirectorylistingusingregularexpressions.//{Args:"D.*\.java"}importjava.io.*;importjava.util.*;importjava.util.regex.*;importcom.bruceeckel.util.*;publicclassDirList{publicstaticvoidmain(String[]args){Filepath=newFile(".");String[]list;if(args.length==0)list=path.list();elselist=path.list(newDirFilter(args[0]));Arrays.sort(list,newAlphabeticComparator());for(inti=0;i<list.length;i++)System.out.println(list[i]);}}classDirFilterimplementsFilenameFilter{privatePatternpattern;publicDirFilter(Stringregex){pattern=Ppile(regex);}publicbooleanaccept(Filedir,Stringname){//Strippathinformation,searchforregex:returnpattern.matcher(newFile(name).getName()).matches();}}///:~DirFilter实现了FilenameFilter接口。我们来看看FilenameFilter究竟有多简单:publicinterfaceFilenameFilter{booleanaccept(Filedir,Stringname);}也就是说,这类对象的任务就是提供一个accept()的方法。之所以要创建这个类,就是要给list()提供一个accept()方法,这样当list()判断该返回哪些文件名的时候,能够"回过头来调用"accept()方法。因此,这种结构通常被称为回调(callback)。更准确地说,由于list()实现了基本功能,而FilenameFilter提供了"对外服务所需的算法",因此这是一种"策略模式(StrategyPattern)"。由于list()拿FilenameFilter对象当参数,因此你可以将任何实现FilenameFilter接口的对象传给它,并以此(甚至是在运行时)控制list()的工作方式。回调能提高程序的灵活性。DirFilter还告诉我们,interface只是包含了一些方法,它没说你只能写这些方法。(但是,你至少要定义接口里有的方法。)这里我们还定义了DirFilter的构造函数。accept()方法需要两个参数,一个是File对象,表示这个文件是在哪个目录里面的;另一个是String,表示文件名。虽然你可以忽略它们中的一个,甚至两个都不管,但是你大概总得用一下文件名吧。记住,list()会对目录里的每个文件调用accept(),并以此判断是不是把它包括到返回值里;这个判断依据就是accept()的返回值。切记,文件名里不能有路径信息。为此你只要用一个String对象来创建File对象,然后再调用这个File对象的getName()就可以了。它会帮你剥离路径信息(以一种平台无关的方式)。然后再在accept()里面用正则表达式(regularexpression)的matcher对象判断,regex是否与文件名相匹配。兜完这个圈子,list()方法返回了一个数组。匿名内部类这是用匿名内部类(详见第八章)来重写程序的绝佳机会。下面我们先创建一个返回FilenameFilter的filter()方法。//:c12:DirList2.java//Usesanonymousinnerclasses.//{Args:"D.*\.java"}importjava.io.*;importjava.util.*;importjava.util.regex.*;importcom.bruceeckel.util.*;publicclassDirList2{publicstaticFilenameFilterfilter(finalStringregex){//Creationofanonymousinnerclass:returnnewFilenameFilter(){privatePatternpattern=Ppile(regex);publicbooleanaccept(Filedir,Stringname){returnpattern.matcher(newFile(name).getName()).matches();}};//Endofanonymousinnerclass}publicstaticvoidmain(String[]args){Filepath=newFile(".");String[]list;if(args.length==0)list=path.list();elselist=path.list(filter(args[0]));Arrays.sort(list,newAlphabeticComparator());for(inti=0;i<list.length;i++)System.out.println(list[i]);}}///:~注意,filter()的参数必须是final的。要想在匿名内部类里使用其作用域之外的对象,只能这么做。这是对前面所讲的代码的改进,现在FilenameFilter类已经与DirList2紧紧地绑在一起了。不过你还可以更进一步,把这个匿名内部类定义成list()的参数,这样代码会变得更紧凑://:c12:DirList3.java//Buildingtheanonymousinnerclass"in-place."//{Args:"D.*\.java"}importjava.io.*;importjava.util.*;importjava.util.regex.*;importcom.bruceeckel.util.*;publicclassDirList3{publicstaticvoidmain(finalString[]args){Filepath=newFile(".");String[]list;if(args.length==0)list=path.list();elselist=path.list(newFilenameFilter(){privatePatternpattern=Ppile(args[0]);publicbooleanaccept(Filedir,Stringname){returnpattern.matcher(newFile(name).getName()).matches();}});Arrays.sort(list,newAlphabeticComparator());for(inti=0;i<list.length;i++)System.out.println(list[i]);}}///:~现在该轮到main()的参数成final了,因为匿名内部类要用它的arg[0]了。这个例子告诉我们,可以用匿名内部类来创建专门供特定问题用的,一次性的类。这种做法的好处是,它能把解决某个问题的代码全都集中到一个地方。但是从另一角度来说,这样做会使代码的可读性变差,所以要慎重。查看与创建目录File类的功能不仅限于显示文件或目录。它还能帮你创建新的目录甚至是目录路径(directorypath),如果目录不存在的话。此外它还能用来检查文件的属性(大小,上次修改的日期,读写权限等),判断File对象表示的是文件还是目录,以及删除文件。下面这段程序演示了File类的一些其他方法(请查阅JDK文档,以了解其全部功能)://:c12:MakeDirectories.java//DemonstratestheuseoftheFileclassto//createdirectoriesandmanipulatefiles.//{Args:MakeDirectoriesTest}importcom.bruceeckel.simpletest.*;importjava.io.*;publicclassMakeDirectories{privatestaticTestmonitor=newTest();privatestaticvoidusage(){System.err.println("Usage:MakeDirectoriespath1...\n"+"Createseachpath\n"+"Usage:MakeDirectories-dpath1...\n"+"Deleteseachpath\n"+"Usage:MakeDirectories-rpath1path2\n"+"Renamesfrompath1topath2");System.exit(1);}privatestaticvoidfileData(Filef){System.out.println("Absolutepath:"+f.getAbsolutePath()+"\nCanread:"+f.canRead()+"\nCanwrite:"+f.canWrite()+"\ngetName:"+f.getName()+"\ngetParent:"+f.getParent()+"\ngetPath:"+f.getPath()+"\nlength:"+f.length()+"\nlastModified:"+f.lastModified());if(f.isFile())System.out.println("It'safile");elseif(f.isDirectory())System.out.println("It'sadirectory");}publicstaticvoidmain(String[]args){if(args.length<1)usage();if(args[0].equals("-r")){if(args.length!=3)usage();Fileold=newFile(args[1]),rname=newFile(args[2]);old.renameTo(rname);fileData(old);fileData(rname);return;//Exitmain}intcount=0;booleandel=false;if(args[0].equals("-d")){count++;del=true;}count--;while(++count<args.length){Filef=newFile(args[count]);if(f.exists()){System.out.println(f+"exists");if(del){System.out.println("deleting..."+f);f.delete();}}else{//Doesn'texistif(!del){f.mkdirs();System.out.println("created"+f);}}fileData(f);}if(args.length==1&&args[0].equals("MakeDirectoriesTest"))monitor.expect(newString[]{"%%(MakeDirectoriesTestexists"+"|createdMakeDirectoriesTest)","%%Absolutepath:"+"\\S+MakeDirectoriesTest","%%Canread:(true|false)","%%Canwrite:(true|false)","getName:MakeDirectoriesTest","getParent:null","getPath:MakeDirectoriesTest","%%length:\\d+","%%lastModified:\\d+","It'sadirectory"});}}///:~在fileData()演示了全套查询文件和目录路径信息的方法。main()的第一条指令就是执行renameTo()。它会把文件重命名成(或者说移动到)新的目录,也就是参数所给出的目录。而参数本身就是一个File对象。这个方法也适用于目录。如果你试过上面那段程序,就会发现,你能用它创建任意复杂的目录路径,因为mkdirs()已经帮你打理好了。输入与输出I/O类库常使用"流(stream)"这种抽象。所谓"流"是一种能生成或接受数据的,代表数据的源和目标的对象。流把I/O设备内部的具体操作给隐藏起来了。正如JDK文档所显示的,Java的I/O类库分成输入和输出两大部分。所有InputStream和Reader的派生类都有一个基本的,继承下来的,能读取单个或byte数组的read()方法。同理,所有OutputStream和Writer的派生类都有一个基本的,能写入单个或byte数组的write()方法。但通常情况下,你是不会去用这些方法的;它们是给其它类用的——而后者会提供一些更实用的接口。因此,你很少会碰到只用一个类就能创建一个流的情形,实际上你得把多个对象叠起来,并以此来获取所需的功能。Java的流类库之所以会那么让人犯晕,最主要的原因就是"你必须为创建一个流而动用多个对象"。我们最好还是根据其功能为这些class归个类。Java1.0的类库设计者们是从决定"让所有与输入相关的类去继承InputStream"入手的。同理,所有与输出相关的类就该继承OutputStream了。添加属性与适用的接口使用"分层对象(layeredobjects)",为单个对象动态地,透明地添加功能的做法,被称为DecoratorPattern。(模式[61]是ThinkinginPatterns(withJava)的主题。)Decorator模式要求所有包覆在原始对象之外的对象,都必须具有与之完全相同的接口。这使得decorator的用法变得非常的透明--无论对象是否被decorate过,传给它的消息总是相同的。这也是JavaI/O类库要有"filter(过滤器)"类的原因:抽象的"filter"类是所有decorator的基类。(decorator必须具有与它要包装的对象的全部接口,但是decorator可以扩展这个接口,由此就衍生出了很多"filter"类)。Decorator模式常用于如下的情形:如果用继承来解决各种需求的话,类的数量会多到不切实际的地步。Java的I/O类库需要提供很多功能的组合,于是decorator模式就有了用武之地。[62]但是decorator有个缺点,在提高编程的灵活性的同时(因为你能很容易地混合和匹配属性),也使代码变得更复杂了。Java的I/O类库之所以会这么怪,就是因为它"必须为一个I/O对象创建很多类",也就是为一个"核心"I/O类加上很多decorator。为InputStream和OutputStream定义decorator类接口的类,分别是FilterInputStream和FilterOutputStream。这两个名字都起得不怎么样。FilterInputStream和FilterOutputStream都继承自I/O类库的基类InputStream和OutputStream,这是decorator模式的关键(惟有这样decorator类的接口才能与它要服务的对象的完全相同)。用FilterInputStream读取InputStreamFilterInputStream及其派生类有两项重要任务。DataInputStream可以读取各种primitive及String。(所有的方法都以"read"打头,比如readByte(),readFloat())。它,以及它的搭档DataOutputStream,能让你通过流将primitive数据从一个地方导到另一个地方。这些"地方"都列在表12-1里。其它的类都是用来修改InputStream的内部行为的:是不是做缓冲,是不是知道它所读取的行信息(允许你读取行号或设定行号),是不是会弹出单个字符。后两个看上去更像是给编译器用的(也就是说,它们大概是为Java编译器设计的),所以通常情况下,你是不大会用到它们的。不论你用哪种I/O设备,输入的时候,最好都做缓冲。所以对I/O类库来说,比较明智的做法还是把不缓冲当特例(或者去直接调用方法),而不是像现在这样把缓冲当作特例。JAVATheJavaI/OSystemCreatingagoodinput/output(I/O)systemisoneofthemoredifficulttasksforthelanguagedesigner.Thisisevidencedbythenumberofdifferentapproaches.Thechallengeseemstobeincoveringalleventualities.NotonlyaretheredifferentsourcesandsinksofI/Othatyouwanttocommunicatewith(files,theconsole,networkconnections,etc.),butyouneedtotalktotheminawidevarietyofways(sequential,random-access,buffered,binary,character,bylines,bywords,etc.).TheJavalibrarydesignersattackedthisproblembycreatinglotsofclasses.Infact,therearesomanyclassesforJava’sI/Osystemthatitcanbeintimidatingatfirst(ironically,theJavaI/Odesignactuallypreventsanexplosionofclasses).TherewasalsoasignificantchangeintheI/OlibraryafterJava1.0,whentheoriginalbyte-orientedlibrarywassupplementedwithchar-oriented,Unicode-basedI/Oclasses.InJDK1.4,thenioclasses(for“newI/O,”anamewe’llstillbeusingyearsfromnow)wereaddedforimprovedperformanceandfunctionality.Asaresult,thereareafairnumberofclassestolearnbeforeyouunderstandenoughofJava’sI/Opicturethatyoucanuseitproperly.Inaddition,it’sratherimportanttounderstandtheevolutionhistoryoftheI/Olibrary,evenifyourfirstreactionis“don’tbothermewithhistory,justshowmehowtouseit!”Theproblemisthatwithoutthehistoricalperspective,youwillrapidlybecomeconfusedwithsomeoftheclassesandwhenyoushouldandshouldn’tusethem.ThischapterwillgiveyouanintroductiontothevarietyofI/OclassesinthestandardJavalibraryandhowtousethem.TheFileclassBeforegettingintotheclassesthatactuallyreadandwritedatatostreams,we’lllookatautilityprovidedwiththelibrarytoassistyouinhandlingfiledirectoryissues.TheFileclasshasadeceivingname;youmightthinkitreferstoafile,butitdoesn’t.Itcanrepresenteitherthenameofaparticularfileorthenamesofasetoffilesinadirectory.Ifit’sasetoffiles,youcanaskforthatsetusingthelist(
)method,whichreturnsanarrayofString.Itmakessensetoreturnanarrayratherthanoneoftheflexiblecontainerclasses,becausethenumberofelementsisfixed,andifyouwantadifferentdirectorylisting,youjustcreateadifferentFileobject.Infact,“FilePath”wouldhavebeenabetternamefortheclass.Thissectionshowsanexampleoftheuseofthisclass,includingtheassociatedFilenameFilterinterface.AdirectorylisterSupposeyou’dliketoseeadirectorylisting.TheFileobjectcanbelistedintwoways.Ifyoucalllist(
)withnoarguments,you’llgetthefulllistthattheFileobjectcontains.However,ifyouwantarestrictedlist—forexample,ifyouwantallofthefileswithanextensionof.java—thenyouusea“directoryfilter,”whichisaclassthattellshowtoselecttheFileobjectsfordisplay.Here’sthecodefortheexample.Notethattheresulthasbeeneffortlesslysorted(alphabetically)usingthejava.utils.Arrays.sort(
)methodandtheAlphabeticComparatordefinedinChapter11://:c12:DirList.java//Displaysdirectorylistingusingregularexpressions.//{Args:"D.*\.java"}importjava.io.*;importjava.util.*;importjava.util.regex.*;importcom.bruceeckel.util.*;publicclassDirList{publicstaticvoidmain(String[]args){Filepath=newFile(".");String[]list;if(args.length==0)list=path.list();elselist=path.list(newDirFilter(args[0]));Arrays.sort(list,newAlphabeticComparator());for(inti=0;i<list.length;i++)System.out.println(list[i]);}}classDirFilterimplementsFilenameFilter{privatePatternpattern;publicDirFilter(Stringregex){pattern=Ppile(regex);}publicbooleanaccept(Filedir,Stringname){//Strippathinformation,searchforregex:returnpattern.matcher(newFile(name).getName()).matches();}}///:~TheDirFilterclass“implements”theinterfaceFilenameFilter.It’susefultoseehowsimpletheFilenameFilterinterfaceis:publicinterfaceFilenameFilter{booleanaccept(Filedir,Stringname);}Itsaysallthatthistypeofobjectdoesisprovideamethodcalledaccept(
).Thewholereasonbehindthecreationofthisclassistoprovidetheaccept(
)methodtothelist(
)methodsothatlist(
)can“callback”accept(
)todeterminewhichfilenamesshouldbeincludedinthelist.Thus,thisstructureisoftenreferredtoasacallback.Morespecifically,thisisanexampleoftheStrategyPattern,becauselist(
)implementsbasicfunctionality,andyouprovidetheStrategyintheformofaFilenameFilterinordertocompletethealgorithmnecessaryforlist(
)toprovideitsservice.Becauselist(
)takesaFilenameFilterobjectasitsargument,itmeansthatyoucanpassanobjectofanyclassthatimplementsFilenameFiltertochoose(evenatruntime)howthelist(
)methodwillbehave.Thepurposeofacallbackistoprovideflexibilityinthebehaviorofcode.DirFiltershowsthatjustbecauseaninterfacecontainsonlyasetofmethods,you’renotrestrictedtowritingonlythosemethods.(Youmustatleastprovidedefinitionsforallthemethodsinaninterface,however.)Inthiscase,theDirFilterconstructorisalsocreated.Theaccept(
)methodmustacceptaFileobjectrepresentingthedirectorythataparticularfileisfoundin,andaStringcontainingthenameofthatfile.Youmightchoosetouseorignoreeitherofthesearguments,butyouwillprobablyatleastusethefilename.Rememberthatthelist(
)methodiscallingaccept(
)foreachofthefilenamesinthedirectoryobjecttoseewhichoneshouldbeincluded;thisisindicatedbythebooleanresultreturnedbyaccept(
).Tomakesuretheelementyou’reworkingwithisonlythefilenameandcontainsnopathinformation,allyouhavetodoistaketheStringobjectandcreateaFileobjectoutofit,thencallgetName(
),whichstripsawayallthepathinformation(inaplatform-independentway).Thenaccept(
)usesaregularexpressionmatcherobjecttoseeiftheregularexpressionregexmatchesthenameofthefile.Usingaccept(
),thelist(
)methodreturnsanarray.AnonymousinnerclassesThisexampleisidealforrewritingusingananonymousinnerclass(describedinChapter8).Asafirstcut,amethodfilter(
)iscreatedthatreturnsareferencetoaFilenameFilter://:c12:DirList2.java//Usesanonymousinnerclasses.//{Args:"D.*\.java"}importjava.io.*;importjava.util.*;importjava.util.regex.*;importcom.bruceeckel.util.*;publicclassDirList2{publicstaticFilenameFilterfilter(finalStringregex){//Creationofanonymousinnerclass:returnnewFilenameFilter(){privatePatternpattern=Ppile(regex);publicbooleanaccept(Filedir,Stringname){returnpattern.matcher(newFile(name).getName()).matches();}};//Endofanonymousinnerclass}publicstaticvoidmain(String[]args){Filepath=newFile(".");String[]list;if(args.length==0)list=path.list();elselist=path.list(filter(args[0]));Arrays.sort(list,newAlphabeticComparator());for(inti=0;i<list.length;i++)System.out.println(list[i]);}}///:~Notethattheargumenttofilter(
)mustbefinal.Thisisrequiredbytheanonymousinnerclasssothatitcanuseanobjectfromoutsideitsscope.ThisdesignisanimprovementbecausetheFilenameFilterclassisnowtightlyboundtoDirList2.However,youcantakethisapproachonestepfurtheranddefinetheanonymousinnerclassasanargumenttolist(
),inwhichcaseit’sevensmaller://:c12:DirList3.java//Buildingtheanonymousinnerclass"in-place."//{Args:"D.*\.java"}importjava.io.*;importjava.util.*;importjava.util.regex.*;importcom.bruceeckel.util.*;publicclassDirList3{publicstaticvoidmain(finalString[]args){Filepath=newFile(".");String[]list;if(args.length==0)list=path.list();elselist=path.list(newFilenameFilter(){privatePatternpattern=Ppile(args[0]);publicbooleanaccept(Filedir,Stringname){returnpattern.matcher(newFile(name).getName()).matches();}});Arrays.sort(list,newAlphabeticComparator());for(inti=0;i<list.length;i++)System.out.println(list[i]);}}///:~Theargumenttomain(
)isnowfinal,sincetheanonymousinnerclassusesargs[0]directly.Thisshowsyouhowanonymousinnerclassesallowthecreationofspecific,one-offclassestosolveproblems.Onebenefitofthisapproachisthatitkeepsthecodethatsolvesaparticularproblemisolatedtogetherinonespot.Ontheotherhand,itisnotalwaysaseasytoread,soyoumustuseitjudiciously.CheckingforandcreatingdirectoriesTheFileclassismorethanjustarepresentationforanexistingfileordirectory.YoucanalsouseaFileobjecttocreateanewdirectoryoranentiredirectorypathifitdoesn’texist.Youcanalsolookatthecharacteristicsoffiles(size,lastmodificationdate,read/write),seewhetheraFileobjectrepresentsafileoradirectory,anddeleteafile.ThisprogramshowssomeoftheothermethodsavailablewiththeFileclass(seetheHTMLdocumentationfromforthefullset)://:c12:MakeDirectories.java//DemonstratestheuseoftheFileclassto//createdirectoriesandmanipulatefiles.//{Args:MakeDirectoriesTest}importcom.bruceeckel.simpletest.*;importjava.io.*;publicclassMakeDirectories{privatestaticTestmonitor=newTest();privatestaticvoidusage(){System.err.println("Usage:MakeDirectoriespath1...\n"+"Createseachpath\n"+"Usage:MakeDirectories-dpath1...\n"+"Deleteseachpath\n"+"Usage:MakeDirectories-rpath1path2\n"+"Renamesfrompath1topath2");System.exit(1);}privatestaticvoidfileData(Filef){System.out.println("Absolutepath:"+f.getAbsolutePath()+"\nCanread:"+f.canRead()+"\nCanwrite:"+f.canWrite()+"\ngetName:"+f.getName()+"\ngetParent:"+f.getParent()+"\ngetPath:"+f.getPath()+"\nlength:"+f.length()+"\nlastModified:"+f.lastModified());if(f.isFile())System.out.println("It'safile");elseif(f.isDirectory())System.out.println("It'sadirectory");}publicstaticvoidmain(String[]args){if(args.length<1)usage();if(args[0].equals("-r")){if(args.length!=3)usage();Fileold=newFile(args[1]),rname=newFile(args[2]);old.renameTo(rname);fileData(old);fileData(rname);return;//Exitmain}intcount=0;booleandel=false;if(args[0].equals("-d")){count++;del=true;}count--;while(++count<args.length){Filef=newFile(args[count]);if(f.exists()){System.out.println(f+"exists");if(del){System.out.println("deleting..."+f);f.delete();}}else{//Doesn'texistif(!del){f.mkdirs();System.out.println("created"+f);}}fileData(f);}if(args.length==1&&args[0].equals("MakeDirectoriesTest"))monitor.expect(newString[]{"%%(MakeDirectoriesTestexists"+"|createdMakeDirectoriesTest)","%%Absolutepath:"+"\\S+MakeDirectoriesTest","%%Canread:(true|false)","%%Canwrite:(true|false)","getName:MakeDirectoriesTest","getParent:null","getPath:MakeDirectoriesTest","%%length:\\d+","%%lastModified:\\d+","It'sadirectory"});}}///:~InfileData(
)youcanseevariousfileinvestigationmethodsusedtodisplayinformationaboutthefileordirectorypath.Thefirstmethodthat’sexercisedbymain(
)isrenameTo(
),whichallowsyoutorename(ormove)afiletoanentirelynewpathrepresentedbytheargument,whichisanotherFileobject.Thisalsoworkswithdirectoriesofanylength.Ifyouexperimentwiththeprecedingprogram,you’llfindthatyoucanmakeadirectorypathofanycomplexity,becausemkdirs(
)willdoalltheworkforyou.InputandoutputI/Olibrariesoftenusetheabstractionofastream,whichrepresentsanydatasourceorsinkasanobjectcapableofproducingorreceivingpiecesofdata.ThestreamhidesthedetailsofwhathappenstothedatainsidetheactualI/Odevice.TheJavalibraryclassesforI/Oaredividedbyinputandoutput,asyoucanseebylookingattheclasshierarchyintheJDKdocumentation.Byinheritance,everythingderivedfromtheInputStreamorReaderclasseshavebasicmethodscalledread(
)forreadingasinglebyteorarrayofbytes.Likewise,everythingderivedfromOutputStreamorWriterclasseshavebasicmethodscalledwrite(
)forwritingasinglebyteorarrayofbytes.However,youwon’tgenerallyusethesemethods;theyexistsothatotherclassescanusethem—theseotherclassesprovideamoreusefulinterface.Thus,you’llrarelycreateyourstreamobjectbyusingasingleclass,butinsteadwilllayermultipleobjectstogethertoprovideyourdesiredfunctionality.ThefactthatyoucreatemorethanoneobjecttocreateasingleresultingstreamistheprimaryreasonthatJava’sstreamlibraryisconfusing.It’shelpfultocategorizetheclassesbytheirfunctionality.InJava1.0,thelibrarydesignersstartedbydecidingthatallclassesthathadanythingtodowithinputwouldbeinheritedfromInputStream,andallclassesthatwereassociatedwithoutputwouldbeinheritedfromOutputStream.Addingattributes
andusefulinterfacesTheuseoflayeredobjectstodynamicallyandtransparentlyaddresponsibilitiestoindividualobjectsisreferredtoastheDecoratorpattern.(Patterns[61]arethesubjectofThinkinginPatterns(withJava)atwww.BruceE.)Thedecoratorpatternspecifiesthatallobjectsthatwraparoundyourinitialobjecthavethesameinterface.Thismakesthebasicuseofthedecoratorstransparent—yousendthesamemessagetoanobjectwhetherithasbeendecoratedornot.Thisisthereasonfortheexistenceofthe“filter”classesintheJavaI/Olibrary:Theabstract“filter”classisthebaseclassforallthedecorators.(Adecoratormusthavethesameinterfaceastheobjectitdecorates,butthedecoratorcanalsoextendtheinterface,whichoccursinseveralofthe“filter”classes).Decoratorsareoftenusedwhensimplesubclassingresultsinalargenumberofclassesinordertosatisfyeverypossiblecombinationthatisneeded—somanyclassesthatitbecomesimpractical.TheJavaI/Olibraryrequiresmanydifferentcombinationsoffeatures,andthisisthejustificationforusingthedecoratorpattern.[62]Thereisadrawbacktothedecoratorpattern,however.Decoratorsgiveyoumuchmoreflexibilitywhileyou’rewritingaprogram(sinceyoucaneasilymixandmatchattributes),buttheyaddcomplexitytoyourcode.ThereasonthattheJavaI/Olibraryisawkwardtouseisthatyoumustcreatemanyclasses—the“core”I/Otypeplusallthedecorators—inordertogetthesingleI/Oobjectthatyouwant.TheclassesthatprovidethedecoratorinterfacetocontrolaparticularInputStreamorOutputStreamaretheFilterInputStreamandFilterOutputStream,whichdon’thaveveryintuitivenames.FilterInputStreamandFilterOutputStreamarederivedfromthebaseclassesoftheI/Olibrary,InputStreamandOutputStream,whichisthekeyrequirementofthedecorator(sothatitprovidesthecommoninterfacetoalltheobjectsthatarebeingdecorated).ReadingfromanInputStream
withFilterInputStreamTheFilterInputStreamclassesaccomplishtwosignificantlydifferentthings.DataInputStreamallowsyoutoreaddifferenttypesofprimitivedataaswellasStringobjects.(Allthemethodsstartwith“read,”suchasreadByte(
),readFloat(
),etc.)This,alongwithitscompanionDataOutputStream,allowsyoutomoveprimitivedatafromoneplacetoanotherviaastream.These“places”aredeterminedbytheclassesinTable12-1.TheremainingclassesmodifythewayanInputStreambehavesinternally:whetherit’sbufferedorunbuffered,ifitkeepstrackofthelinesit’sreading(allowingyoutoaskforlinenumbersorsetthelinenumber),andwhetheryoucanpushbackasinglecharacter.Thelasttwoclasseslookalotlikesupportforbuildingacompiler(thatis,theywereprobablyaddedtosupporttheconstructionoftheJavacompiler),soyouprobablywon’tusethemingeneralprogramming.You’llneedtobufferyourinputalmosteverytime,regardlessoftheI/Odeviceyou’reconnectingto,soitwouldhavemademoresensefortheI/Olibrarytomakeaspecialcase(orsimplyamethodcall)forunbufferedinputratherthan
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 园林景观石材安装合同
- 新学期自律保证书范文
- 九年级化学上册 第五单元 定量研究化学反应 第一节 化学反应中的质量守恒同步教案 (新版)鲁教版
- 2024秋九年级语文上册 第二单元 写作 观点要明确教案 新人教版
- 2024-2025学年新教材高中政治 第三课 只有中国特色社会主义才能发展中国 2 中国特色社会主义的创立、发展和完善(2)教案 部编版必修1
- 2024八年级数学下册 第22章 四边形22.3三角形的中位线教案(新版)冀教版
- 2024-2025学年高中历史 第二单元 凡尔赛-华盛顿体系下的世界 第1课 巴黎和会(4)教学教案 新人教版选修3
- 2023六年级语文下册 第二单元 口语交际:同读一本书配套教案 新人教版
- 2023三年级数学上册 五 周长第3课时 长方形的周长说课稿 北师大版
- 2023七年级英语上册 Module 6 A trip to the zoo Unit 1 Does it eat meat教案 (新版)外研版
- 职业健康整改计划
- 国家职业技术技能标准 3-02-03-01 消防员(2022年版)
- GB/T 36242-2018燃气流量计体积修正仪
- GB/T 2818-2014井用潜水异步电动机
- 5 汪曾祺《跑警报》.电子教案教学课件
- 叙事疗法课件
- 国家开放大学电大《计算机应用基础(本)》终结性考试试题答案(格式已排好)任务一
- 店长交接表模板(最新)
- 阿米巴经营管理课件
- 牙列缺损的固定义齿修复课件
- 小学质量检测汇报材料范文推荐11篇
评论
0/150
提交评论