最新知识,让你享有最新知识带来好运。6
第17章项目
本章包括了一系列项目,它们都以本书简介内容为基本,并对初期章节进行了一定限度扩充。
与此前经历过项目相比,这儿大多数项目都明显要复杂得多,它们充分演示了新技术以及类库运用。
17.1 文字解决
如果您有C或C++经验,那么最开始也许会对Java控制文本能力感到怀疑。事实上,咱们最胆怯就是速度特别慢,这也许妨碍咱们创造能力发挥。然而,Java相应工具(特别是String类)具备很强功能,就象本节例子展示那样(并且性能也有一定限度提高)。
正如人们即将看到那样,建立这些例子目都是为理解决本书编制过程中遇到某些问题。但是,它们能力并非仅止于此。通过简朴改造,即可让它们在其她场合大显身手。除此以外,它们还揭示出了本书此前没有强调过一项Java特性。
17.1.1 提取代码列表
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对象。除此以外,尚有一项特别安全办法:在每个子目录里都放入一种空文献;那个文献名字指出在那个子目录里应到多少个文献。
下面是完整代码,背面会对它进行详细阐明:
959-968页程序
咱们注意到package语句已经作为注释标志出来了。由于这是本章第一种程序,因此package语句是必须,用它告诉CodePackager已改换到另一章。但是把它放入包里却会成为一种问题。当咱们创立一种包时候,需要将成果程序同一种特定目录构造联系在一起,这一做法对本书大多数例子都是合用。但在这里,CodePackager程序必要在一种专用目录里编译和运营,因此package语句作为注释标记出去。但对CodePackager来说,它“看起来”依然象一种普通package语句,由于程序还不是特别复杂,不能侦查到多行注释(没有必要做得这样复杂,这里只规定以便就行)。
头两个类是“支持/工具”类,作用是使程序剩余某些在编写时更加连贯,也更便于阅读。第一种是Pr,它类似ANSI Cperror库,两者都能打印出一条错误提示消息(但同步也会退出程序)。第二个类将文献创立过程封装在内,这个过程已在第10章简介过了;人们已经懂得,这样做不久就会变得非常累赘和
麻烦。为解决这个问题,第10章提供方案致力于新类创立,但这儿“静态”办法已经使用过了。在那些办法中,正常违例会被捕获,并相应地进行解决。这些办法使剩余代码显得更加清爽,更易阅读。
协助解决问题第一种类是SourceCodeFile(源码文献),它代表本书一种源码文献包括所有信息(内容、文献名以及目录)。它同步还包括了一系列String 常数,分别代表一种文献开始与结束;在打包文献内使用一种标记;当前系统换行符;文献途径分隔符(注意要用Property()侦查本地版本是
什么);以及一大段版权声明,它是从下面这个文献里提取出来:
969-967页程序
从一种打包文献中提取文献时,当时所用系统文献分隔符也会标注出来,以便用本地系统合用符号替代它。
当前章子目录保存在chapter字段中,它初始化成c02(人们可注意一下第2章列表正好没有包括一种打包语句)。只有在当前文献里发现一种package (打包)语句时,chapter字段才会发生变化。
1. 构建一种打包文献
第一种构建器用于从本书ASCII文本版里提取出一种文献。发出调用代码(在列表里较深地方)会读入并检查每一行,直到到与一种列表开头相符为止。在这个时候,它就会新建一种SourceCodeFile对象,将第一行内容(已经由调用代码读入了)传递给它,同步还要传递BufferedReader对象,以便在这个缓冲区中提取源码列表剩余内容。
从这时起,人们会发现String办法被频繁运用。为提取出文献名,需调用substring()过载版本,令其从一种起始偏移开始,始终读到字串末尾,从而形成一种“子串”。为算出这个起始索引,先要用length()得出startMarker总长,再用trim()删除字串头尾多余空格。第一行在文献名后也也许有某些字符;它们是用in
dexOf()侦测出来。若没有发现到咱们想寻字符,就返回-1;若到那些字符,就返回它们第一次浮现位置。注意这也是indexOf()一种过载版本,采用一种字串作为参数,而非一种字符。
解析出并保存好文献名后,第一行会被置入字串contents中(该字串用于保存源码清单完整正文)。随后,将剩余代码行读入,并合并进入contents字串。固然事情并没有想象那么简朴,由于特定状况需加以特别控制。一种状况是错误检查:若直接遇到一种startMarker(起始标记),表白当前操作这个代码列表没有设立一种结束标记。这属于一种出错条件,需要退出程序。
另一种特殊状况与package核心字关于。尽管Java是一种自由形式语言,但这个程序规定package核心字必要位于行首。若发现package核心字,就通过检查位于开头空格以及位于末尾分号,从而提取出包名(注意亦可一次单独操作实现,办法是使用过载substring(),令其同步检查起始和结束索引位置)。随后,将包名中点号替代成特定文献分隔符——固然,这里要假设文献分隔符仅有一种字符长度。尽管这个假设也许对当前所有系统都是合用,但一旦遇到问题,一定不要忘了检查一下这里。
默认操作是将每一行都连接到contents里,同步尚有换行字符,直到遇到一种endMarker(结束标记)为止。该标记指出构建器应当停止了。若在endMarker 之前遇到了文献结尾,就以为存在一种错误。
2. 从打包文献中提取

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。