|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
在性能方面,在windows平台下,.net网页编程可能是占强项,要是把.net网页编程放在sun开发的操作系统上去运行呢?根本就运行不了,.net网页编程对其它操作系统的支持也很弱,性能也可能比不上java。
关于本书每个完全的代码列表(不是代码段),人人无疑会注重到它们都用特别的正文暗号肇端与停止(//:和///:~)。之以是要包含这类标记信息,是为了能将代码从本书主动提取到兼容的源码文件中。在我的前一本书里,我计划了一个体系,可将测试过的代码文件主动兼并到书中。但关于这本书,我发明一种更烦琐的做法是一旦经由过程了最后的测试,就把代码粘贴到书中。并且因为很难第一次就编译经由过程,以是我在书的外部编纂代码。但怎样提取并测试代码呢?这个程序就是关头。假如你盘算办理一个笔墨处置的成绩,那末它也很有益用代价。该例也演示了String类的很多特征。
我起首将整本书都以ASCII文本格局保留成一个自力的文件。CodePackager程序有两种运转形式(在usageString有响应的形貌):假如利用-p标记,程序就会反省一个包括了ASCII文本(即本书的内容)的一个输出文件。它会遍历这个文件,依照正文暗号提掏出代码,并用位于第一行的文件名来决意创立文件利用甚么名字。除此之外,在必要将文件置进一个特别目次的时分,它还会反省package语句(依据由package语句指定的路径选择)。
但如许还不敷。程序还要对包(package)名举行跟踪,从而监督章内产生的变更。因为每章利用的一切包都以c02,c03,c04等等开端,用于标志它们所属的是哪一章(除那些以com开端的之外,它们在对分歧的章举行跟踪的时分会被疏忽)——只需每章的第一个代码列表包括了一个package,以是CodePackager程序能晓得每章产生的变更,并将后续的文件放到新的子目次里。
每一个文件提掏出来时,城市置进一个SourceCodeFile对象,随后再将谁人对象置进一个汇合(前面还会细致报告这个历程)。这些SourceCodeFile对象能够复杂地保留在文件中,那恰是本项目标第二个用处。假如间接挪用CodePackager,不增加-p标记,它就会将一个“打包”文件作为输出。谁人文件随后会被提取(开释)进进独自的文件。以是-p标记的意义就是提掏出来的文件已被“打包”(packed)进进这个单一的文件。
但为何还要云云贫苦地利用打包文件呢?这是因为分歧的盘算机平台用分歧的体例在文件里保留文本信息。个中最年夜的成绩是换行字符的暗示办法;固然,另有大概存在另外一些成绩。但是,Java有一种特别范例的IO数据流——DataOutputStream——它能够包管“不管数据来自何种呆板,只需利用一个DataInputStream收取这些数据,便可用本机准确的格局保留它们”。也就是说,Java卖力把持与分歧平台有关的一切细节,而这恰是Java最具魅力的一点。以是-p标记能将一切工具都保留到单一的文件里,并接纳通用的格局。用户可从Web下载这个文件和Java程序,然后对这个文件运转CodePackager,同时不指定-p标记,文件便会开释到体系中准确的场合(亦可指定另外一个子目次;不然就在以后目次创立子目次)。为确保不会留下与特定平台有关的格局,但凡必要形貌一个文件或路径的时分,我们就利用File对象。除此之外,另有一项出格的平安措施:在每一个子目次里都放进一个空文件;谁人文件的名字指出在谁人子目次里应找到几个文件。
上面是完全的代码,前面会对它举行具体的申明:
- //:CodePackager.java
- //"Packs"and"unpacks"thecodein"Thinking
- //inJava"forcross-platformdistribution.
- /*CommentedsoCodePackagerseesitandstarts
- anewchapterdirectory,butsoyoudont
- havetoworryaboutthedirectorywherethis
- programlives:
- packagec17;
- */
- importjava.util.*;
- importjava.io.*;
- classPr{
- staticvoiderror(Stringe){
- System.err.println("ERROR:"+e);
- System.exit(1);
- }
- }
- classIO{
- staticBufferedReaderdisOpen(Filef){
- BufferedReaderin=null;
- try{
- in=newBufferedReader(
- newFileReader(f));
- }catch(IOExceptione){
- Pr.error("couldnotopen"+f);
- }
- returnin;
- }
- staticBufferedReaderdisOpen(Stringfname){
- returndisOpen(newFile(fname));
- }
- staticDataOutputStreamdosOpen(Filef){
- DataOutputStreamin=null;
- try{
- in=newDataOutputStream(
- newBufferedOutputStream(
- newFileOutputStream(f)));
- }catch(IOExceptione){
- Pr.error("couldnotopen"+f);
- }
- returnin;
- }
- staticDataOutputStreamdosOpen(Stringfname){
- returndosOpen(newFile(fname));
- }
- staticPrintWriterpsOpen(Filef){
- PrintWriterin=null;
- try{
- in=newPrintWriter(
- newBufferedWriter(
- newFileWriter(f)));
- }catch(IOExceptione){
- Pr.error("couldnotopen"+f);
- }
- returnin;
- }
- staticPrintWriterpsOpen(Stringfname){
- returnpsOpen(newFile(fname));
- }
- staticvoidclose(Writeros){
- try{
- os.close();
- }catch(IOExceptione){
- Pr.error("closing"+os);
- }
- }
- staticvoidclose(DataOutputStreamos){
- try{
- os.close();
- }catch(IOExceptione){
- Pr.error("closing"+os);
- }
- }
- staticvoidclose(Readeros){
- try{
- os.close();
- }catch(IOExceptione){
- Pr.error("closing"+os);
- }
- }
- }
- classSourceCodeFile{
- publicstaticfinalString
- startMarker="//:",//Startofsourcefile
- endMarker="}///:~",//Endofsource
- endMarker2="};///:~",//C++fileend
- beginContinue="}///:Continued",
- endContinue="///:Continuing",
- packMarker="###",//Packedfileheadertag
- eol=//Lineseparatoroncurrentsystem
- System.getProperty("line.separator"),
- filesep=//Systemsfilepathseparator
- System.getProperty("file.separator");
- publicstaticStringcopyright="";
- static{
- try{
- BufferedReadercr=
- newBufferedReader(
- newFileReader("Copyright.txt"));
- Stringcrin;
- while((crin=cr.readLine())!=null)
- copyright+=crin+"
- ";
- cr.close();
- }catch(Exceptione){
- copyright="";
- }
- }
- privateStringfilename,dirname,
- contents=newString();
- privatestaticStringchapter="c02";
- //Thefilenameseparatorfromtheoldsystem:
- publicstaticStringoldsep;
- publicStringtoString(){
- returndirname+filesep+filename;
- }
- //Constructorforparsingfromdocumentfile:
- publicSourceCodeFile(StringfirstLine,
- BufferedReaderin){
- dirname=chapter;
- //Skippastmarker:
- filename=firstLine.substring(
- startMarker.length()).trim();
- //Findspacethatterminatesfilename:
- if(filename.indexOf()!=-1)
- filename=filename.substring(
- 0,filename.indexOf());
- System.out.println("found:"+filename);
- contents=firstLine+eol;
- if(copyright.length()!=0)
- contents+=copyright+eol;
- Strings;
- booleanfoundEndMarker=false;
- try{
- while((s=in.readLine())!=null){
- if(s.startsWith(startMarker))
- Pr.error("Noendoffilemarkerfor"+
- filename);
- //Forthisprogram,nospacesbefore
- //the"package"keywordareallowed
- //intheinputsourcecode:
- elseif(s.startsWith("package")){
- //Extractpackagename:
- Stringpdir=s.substring(
- s.indexOf()).trim();
- pdir=pdir.substring(
- 0,pdir.indexOf(;)).trim();
- //Capturethechapterfromthepackage
- //ignoringthecomsubdirectories:
- if(!pdir.startsWith("com")){
- intfirstDot=pdir.indexOf(.);
- if(firstDot!=-1)
- chapter=
- pdir.substring(0,firstDot);
- else
- chapter=pdir;
- }
- //Convertpackagenametopathname:
- pdir=pdir.replace(
- .,filesep.charAt(0));
- System.out.println("package"+pdir);
- dirname=pdir;
- }
- contents+=s+eol;
- //Movepastcontinuations:
- if(s.startsWith(beginContinue))
- while((s=in.readLine())!=null)
- if(s.startsWith(endContinue)){
- contents+=s+eol;
- break;
- }
- //Watchforendofcodelisting:
- if(s.startsWith(endMarker)||
- s.startsWith(endMarker2)){
- foundEndMarker=true;
- break;
- }
- }
- if(!foundEndMarker)
- Pr.error(
- "EndmarkernotfoundbeforeEOF");
- System.out.println("Chapter:"+chapter);
- }catch(IOExceptione){
- Pr.error("Errorreadingline");
- }
- }
- //Forrecoveringfromapackedfile:
- publicSourceCodeFile(BufferedReaderpFile){
- try{
- Strings=pFile.readLine();
- if(s==null)return;
- if(!s.startsWith(packMarker))
- Pr.error("Cantfind"+packMarker
- +"in"+s);
- s=s.substring(
- packMarker.length()).trim();
- dirname=s.substring(0,s.indexOf(#));
- filename=s.substring(s.indexOf(#)+1);
- dirname=dirname.replace(
- oldsep.charAt(0),filesep.charAt(0));
- filename=filename.replace(
- oldsep.charAt(0),filesep.charAt(0));
- System.out.println("listing:"+dirname
- +filesep+filename);
- while((s=pFile.readLine())!=null){
- //Watchforendofcodelisting:
- if(s.startsWith(endMarker)||
- s.startsWith(endMarker2)){
- contents+=s;
- break;
- }
- contents+=s+eol;
- }
- }catch(IOExceptione){
- System.err.println("Errorreadingline");
- }
- }
- publicbooleanhasFile(){
- returnfilename!=null;
- }
- publicStringdirectory(){returndirname;}
- publicStringfilename(){returnfilename;}
- publicStringcontents(){returncontents;}
- //Towritetoapackedfile:
- publicvoidwritePacked(DataOutputStreamout){
- try{
- out.writeBytes(
- packMarker+dirname+"#"
- +filename+eol);
- out.writeBytes(contents);
- }catch(IOExceptione){
- Pr.error("writing"+dirname+
- filesep+filename);
- }
- }
- //Togeneratetheactualfile:
- publicvoidwriteFile(Stringrootpath){
- Filepath=newFile(rootpath,dirname);
- path.mkdirs();
- PrintWriterp=
- IO.psOpen(newFile(path,filename));
- p.print(contents);
- IO.close(p);
- }
- }
- classDirMap{
- privateHashtablet=newHashtable();
- privateStringrootpath;
- DirMap(){
- rootpath=System.getProperty("user.dir");
- }
- DirMap(StringalternateDir){
- rootpath=alternateDir;
- }
- publicvoidadd(SourceCodeFilef){
- Stringpath=f.directory();
- if(!t.containsKey(path))
- t.put(path,newVector());
- ((Vector)t.get(path)).addElement(f);
- }
- publicvoidwritePackedFile(Stringfname){
- DataOutputStreampacked=IO.dosOpen(fname);
- try{
- packed.writeBytes("###OldSeparator:"+
- SourceCodeFile.filesep+"###
- ");
- }catch(IOExceptione){
- Pr.error("Writingseparatorto"+fname);
- }
- Enumeratione=t.keys();
- while(e.hasMoreElements()){
- Stringdir=(String)e.nextElement();
- System.out.println(
- "Writingdirectory"+dir);
- Vectorv=(Vector)t.get(dir);
- for(inti=0;i<v.size();i++){
- SourceCodeFilef=
- (SourceCodeFile)v.elementAt(i);
- f.writePacked(packed);
- }
- }
- IO.close(packed);
- }
- //Writeallthefilesintheirdirectories:
- publicvoidwrite(){
- Enumeratione=t.keys();
- while(e.hasMoreElements()){
- Stringdir=(String)e.nextElement();
- Vectorv=(Vector)t.get(dir);
- for(inti=0;i<v.size();i++){
- SourceCodeFilef=
- (SourceCodeFile)v.elementAt(i);
- f.writeFile(rootpath);
- }
- //Addfileindicatingfilequantity
- //writtentothisdirectoryasacheck:
- IO.close(IO.dosOpen(
- newFile(newFile(rootpath,dir),
- Integer.toString(v.size())+".files")));
- }
- }
- }
- publicclassCodePackager{
- privatestaticfinalStringusageString=
- "usage:javaCodePackagerpackedFileName"+
- "
- Extractssourcecodefilesfrompacked
- "+
- "versionofTjava.docsourcesinto"+
- "directoriesoffcurrentdirectory
- "+
- "javaCodePackagerpackedFileNamenewDir
- "+
- "ExtractsintodirectoriesoffnewDir
- "+
- "javaCodePackager-psource.txtpackedFile"+
- "
- Createspackedversionofsourcefiles"+
- "
- fromtextversionofTjava.doc";
- privatestaticvoidusage(){
- System.err.println(usageString);
- System.exit(1);
- }
- publicstaticvoidmain(String[]args){
- if(args.length==0)usage();
- if(args[0].equals("-p")){
- if(args.length!=3)
- usage();
- createPackedFile(args);
- }
- else{
- if(args.length>2)
- usage();
- extractPackedFile(args);
- }
- }
- privatestaticStringcurrentLine;
- privatestaticBufferedReaderin;
- privatestaticDirMapdm;
- privatestaticvoid
- createPackedFile(String[]args){
- dm=newDirMap();
- in=IO.disOpen(args[1]);
- try{
- while((currentLine=in.readLine())
- !=null){
- if(currentLine.startsWith(
- SourceCodeFile.startMarker)){
- dm.add(newSourceCodeFile(
- currentLine,in));
- }
- elseif(currentLine.startsWith(
- SourceCodeFile.endMarker))
- Pr.error("filehasnostartmarker");
- //Elseignoretheinputline
- }
- }catch(IOExceptione){
- Pr.error("Errorreading"+args[1]);
- }
- IO.close(in);
- dm.writePackedFile(args[2]);
- }
- privatestaticvoid
- extractPackedFile(String[]args){
- if(args.length==2)//Alternatedirectory
- dm=newDirMap(args[1]);
- else//Currentdirectory
- dm=newDirMap();
- in=IO.disOpen(args[0]);
- Strings=null;
- try{
- s=in.readLine();
- }catch(IOExceptione){
- Pr.error("Cannotreadfrom"+in);
- }
- //Capturetheseparatorusedinthesystem
- //thatpackedthefile:
- if(s.indexOf("###OldSeparator:")!=-1){
- Stringoldsep=s.substring(
- "###OldSeparator:".length());
- oldsep=oldsep.substring(
- 0,oldsep.indexOf(#));
- SourceCodeFile.oldsep=oldsep;
- }
- SourceCodeFilesf=newSourceCodeFile(in);
- while(sf.hasFile()){
- dm.add(sf);
- sf=newSourceCodeFile(in);
- }
- dm.write();
- }
- }///:~
复制代码
我们注重到package语句已作为正文标记出来了。因为这是本章的第一个程序,以是package语句是必须的,用它告知CodePackager已更换到另外一章。可是把它放进包里却会成为一个成绩。当我们创立一个包的时分,必要将了局程序统一个特定的目次布局接洽在一同,这一做法对本书的年夜多半例子都是合用的。但在这里,CodePackager程序必需在一个公用的目次里编译和运转,以是package语句作为正文标志进来。但对CodePackager来讲,它“看起来”仍然象一个一般的package语句,由于程序还不是出格庞大,不克不及侦察到多行正文(没有需要做得这么庞大,这里只需求便利就行)。
头两个类是“撑持/工具”类,感化是使程序残剩的部分在编写时加倍联贯,也更便于浏览。第一个是Pr,它相似ANSIC的perror库,二者都能打印出一条毛病提醒动静(但同时也会加入程序)。第二个类将文件的创立历程封装在内,这个历程已在第10章先容过了;人人已晓得,如许做很快就会变得十分包袱和贫苦。为办理这个成绩,第10章供应的计划努力于新类的创立,但这儿的“静态”办法已利用过了。在那些办法中,一般的背例会被捕捉,并响应地举行处置。这些办法使残剩的代码显得加倍清新,更容易浏览。
匡助办理成绩的第一个类是SourceCodeFile(源码文件),它代表本书一个源码文件包括的一切信息(内容、文件名和目次)。它同时还包括了一系列String常数,分离代表一个文件的入手下手与停止;在打包文件内利用的一个标志;以后体系的换行符;文件路径分开符(注重要用System.getProperty()侦察当地版本是甚么);和一年夜段版权声明,它是从上面这个Copyright.txt文件里提掏出来的:
- //////////////////////////////////////////////////
- //Copyright(c)BruceEckel,1998
- //Sourcecodefilefromthebook"ThinkinginJava"
- //AllrightsreservedEXCEPTasallowedbythe
- //followingstatements:Youmayfreelyusethisfile
- //foryourownwork(personalorcommercial),
- //includingmodificationsanddistributionin
- //executableformonly.Permissionisgrantedtouse
- //thisfileinclassroomsituations,includingits
- //useinpresentationmaterials,aslongasthebook
- //"ThinkinginJava"iscitedasthesource.
- //Exceptinclassroomsituations,youmaynotcopy
- //anddistributethiscode;instead,thesole
- //distributionpointishttp://www.BruceEckel.com
- //(andofficialmirrorsites)whereitis
- //freelyavailable.Youmaynotremovethis
- //copyrightandnotice.Youmaynotdistribute
- //modifiedversionsofthesourcecodeinthis
- //package.Youmaynotusethisfileinprinted
- //mediawithouttheexpresspermissionofthe
- //author.BruceEckelmakesnorepresentationabout
- //thesuitabilityofthissoftwareforanypurpose.
- //Itisprovided"asis"withoutexpressorimplied
- //warrantyofanykind,includinganyimplied
- //warrantyofmerchantability,fitnessfora
- //particularpurposeornon-infringement.Theentire
- //riskastothequalityandperformanceofthe
- //softwareiswithyou.BruceEckelandthe
- //publishershallnotbeliableforanydamages
- //sufferedbyyouoranythirdpartyasaresultof
- //usingordistributingsoftware.Innoeventwill
- //BruceEckelorthepublisherbeliableforany
- //lostrevenue,profit,ordata,orfordirect,
- //indirect,special,consequential,incidental,or
- //punitivedamages,howevercausedandregardlessof
- //thetheoryofliability,arisingoutoftheuseof
- //orinabilitytousesoftware,evenifBruceEckel
- //andthepublisherhavebeenadvisedofthe
- //possibilityofsuchdamages.Shouldthesoftware
- //provedefective,youassumethecostofall
- //necessaryservicing,repair,orcorrection.Ifyou
- //thinkyouvefoundanerror,pleaseemailall
- //modifiedfileswithclearlycommentedchangesto:
- //Bruce@EckelObjects.com.(pleaseusethesame
- //addressfornon-codeerrorsfoundinthebook).
- //////////////////////////////////////////////////
复制代码
从一个打包文件中提取文件时,现在所用体系的文件分开符也会标注出来,以便用当地体系合用的标记交换它。
以后章的子目次保留在chapter字段中,它初始化成c02(人人可注重一下第2章的列表恰好没有包括一个打包语句)。只要在以后文件里发明一个package(打包)语句时,chapter字段才会产生改动。
1.构建一个打包文件
第一个构建器用于从本书的ASCII文本版里提掏出一个文件。收回挪用的代码(在列内外较深的中央)会读进并反省每行,直到找到与一个列表的开首符合的为止。在这个时分,它就会新建一个SourceCodeFile对象,将第一行的内容(已由挪用代码读进了)传送给它,同时还要传送BufferedReader对象,以便在这个缓冲区中提取源码列表残剩的内容。
从这时候起,人人会发明String办法被频仍使用。为提掏出文件名,需挪用substring()的过载版本,令其从一个肇端偏移入手下手,一向读到字串的开端,从而构成一个“子串”。为算出这个肇端索引,先要用length()得出startMarker的总长,再用trim()删除字串头尾过剩的空格。第一行在文件名后也大概有一些字符;它们是用indexOf()侦测出来的。若没有发明找到我们想寻觅的字符,就前往-1;若找到那些字符,就前往它们第一次呈现的地位。注重这也是indexOf()的一个过载版本,接纳一个字串作为参数,而非一个字符。
剖析出并保留好文件名后,第一行会被置进字串contents中(该字串用于保留源码清单的完全注释)。随后,将残剩的代码行读进,并兼并进进contents字串。固然事变并没有设想的那末复杂,由于特定的情形需加以出格的把持。一种情形是毛病反省:若间接碰到一个startMarker(肇端标志),标明以后操纵的这个代码列表没有设置一个停止标志。这属于一个堕落前提,必要加入程序。
另外一种特别情形与package关头字有关。只管Java是一种自在情势的言语,但这个程序请求package关头字必需位于行首。若发明package关头字,就经由过程反省位于开首的空格和位于开端的分号,从而提掏出包名(注重亦可一次独自的操纵完成,办法是利用过载的substring(),令其同时反省肇端和停止索引地位)。随后,将包名中的点号交换成特定的文件分开符——固然,这里要假定文件分开符唯一一个字符的长度。只管这个假定大概对今朝的一切体系都是合用的,但一旦碰到成绩,必定不要忘了反省一下这里。
默许操纵是将每行都毗连到contents里,同时另有换行字符,直到碰到一个endMarker(停止标志)为止。该标志指出构建器应该中断了。若在endMarker之前碰到了文件开头,就以为存在一个毛病。
2.从打包文件中提取
第二个构建器用于将源码文件从打包文件中恢复(提取)出来。在这儿,作为挪用者的办法不用忧虑会跳过一些两头文本。打包文件包括了一切源码文件,它们互相间严密地靠在一同。必要传送给该构建器的仅仅是一个BufferedReader,它代表着“信息源”。构建器会从中提掏出本人必要的信息。但在每一个代码列表入手下手的中央另有一些设置信息,它们的身份是用packMarker(打包标志)指出的。若packMarker不存在,意味着挪用者试图用毛病的办法来利用这个构建器。
一旦发明packMarker,就会将其剥离出来,并提掏出目次名(用一个#开头)和文件名(直到行末)。不论在哪一种情形下,旧分开符城市被交换本钱地合用的一个分开符,这是用Stringreplace()办法完成的。老的分开符被置于打包文件的开首,在代码列表稍靠后的一部分便可看到是怎样把它提掏出来的。
构建器剩下的部分就十分复杂了。它读进每行,把它兼并到contents里,直到碰见endMarker为止。
3.程序列表的存取
接上去的一系列办法是复杂的会见器:directory()、filename()(注重办法大概与字段有不异的拼写和巨细写情势)和contents()。而hasFile()用于指出这个对象是不是包括了一个文件(很快就会晓得为何必要这个)。
最初三个办法努力于将这个代码列表写进一个文件——要末经由过程writePacked()写进一个打包文件,要末经由过程writeFile()写进一个Java源码文件。writePacked()必要的独一工具就是DataOutputStream,它是在其余中央翻开的,代表着筹办写进的文件。它先把头信息置进第一行,再挪用writeBytes()将contents(内容)写成一种“通用”格局。
筹办写Java源码文件时,必需先把文件建好。这是用IO.psOpen()完成的。我们必要向它传送一个File对象,个中不但包括了文件名,也包括了路径信息。但如今的成绩是:这个路径实践存在吗?用户大概决意将一切源码目次都置进一个完整分歧的子目次,谁人目次多是尚不存在的。以是在正式写每一个文件之前,都要挪用File.mkdirs()办法,建好我们想向个中写进文件的目次路径。它可一次性建好全部路径。
4.整套列表的包涵
以子目次的情势构造代码列表长短常便利的,只管这请求先在内存中建好整套列表。之以是要如许做,另有另外一个很有压服力的缘故原由:为了构建更“安康”的体系。也就是说,在创立代码列表的每一个子目次时,城市到场一个分外的文件,它的名字包括了谁人目次内应有的文件数量。
DirMap类可匡助我们完成这一效果,并无效地演示了一个“多重映照”的概述。这是经由过程一个散列表(Hashtable)完成的,它的“键”是筹办创立的子目次,而“值”是包括了谁人特定目次中的SourceCodeFile对象的Vector对象。以是,我们在这儿并非将一个“键”映照(或对应)到一个值,而是经由过程对应的Vector,将一个键“多重映照”到一系列值。只管这听起来仿佛很庞大,但详细完成时倒是十分复杂和间接的。人人能够看到,DirMap类的年夜多半代码都与向文件中的写进有关,而非与“多重映照”有关。与它有关的代码仅少少数罢了。
可经由过程两种体例创建一个DirMap(目次映照或对应)干系:默许构建器假定我们但愿目次从以后地位向下睁开,而另外一个构建器让我们为肇端目次指定一个备用的“相对”路径。
add()办法是一个接纳的举动对照麋集的场合。起首将directory()从我们想增加的SourceCodeFile里提掏出来,然后反省散列表(Hashtable),看看个中是不是已包括了谁人键。假如没有,就向散列表到场一个新的Vector,并将它同谁人键联系关系到一同。到这时候,不论接纳的是甚么路子,Vector都已就位了,能够将它提掏出来,以便增加SourceCodeFile。因为Vector可象如许同散列表便利地兼并到一同,以是我们从两方面都能感到得十分便利。
写一个打包文件时,需翻开一个筹办写进的文件(看成DataOutputStream翻开,使数据具有“通用”性),并在第一行写进与老的分开符有关的头信息。接着发生对Hashtable键的一个Enumeration(列举),并遍历个中,选择每个目次,并获得与谁人目次有关的Vector,使谁人Vector中的每一个SourceCodeFile都能写进打包文件中。
用write()将Java源码文件写进它们对应的目次时,接纳的办法几近与writePackedFile()完整分歧,由于两个办法都只需复杂挪用SourceCodeFile中得当的办法。但在这里,根路径会传送给SourceCodeFile.writeFile()。一切文件都写好后,名字中指定了已写文件数目的谁人附加文件也会被写进。
5.主程序
后面先容的那些类都要在CodePackager顶用到。人人起首看到的是用法字串。一旦终极用户不准确地挪用了程序,就会打印出先容准确用法的这个字串。挪用这个字串的是usage()办法,同时还要加入程序。main()独一的义务就是判别我们但愿创立一个打包文件,仍是但愿从一个打包文件中提取甚么工具。随后,它卖力包管利用的是准确的参数,并挪用得当的办法。
创立一个打包文件时,它默许位于以后目次,以是我们用默许构建器创立DirMap。翻开文件后,个中的每行城市读进,并反省是不是切合特别的前提:
(1)若行首是一个用于源码列表的肇端标志,就新建一个SourceCodeFile对象。构建器会读进源码列表剩下的一切内容。了局发生的句柄将间接到场DirMap。
(2)若行首是一个用于源码列表的停止标志,标明某个中央呈现毛病,由于停止标志应该只能由SourceCodeFile构建器发明。
提取/开释一个打包文件时,提掏出来的内容可进进以后目次,亦可进进另外一个备用目次。以是必要响应地创立DirMap对象。翻开文件,并将第一行读进。老的文件路径分开符信息将从这一行中提掏出来。随后依据输出来创立第一个SourceCodeFile对象,它会到场DirMap。只需包括了一个文件,新的SourceCodeFile对象就会创立并到场(创立的最初一个用光输出内容后,会复杂地前往,然后hasFile()会前往一个毛病)。
用java开发web只要两本书:一本是关于java基础的,一本是关于jsp、servlet的就可以了。开发周期长,我就来讲句题外话,现在有很多思想都是通过java来展现。 |
|