仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 928|回复: 19
打印 上一主题 下一主题

[学习教程] 发布一篇提代替码列表

[复制链接]
不帅 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-1-18 11:34:52 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

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对象。除此之外,另有一项出格的平安措施:在每一个子目次里都放进一个空文件;谁人文件的名字指出在谁人子目次里应找到几个文件。
上面是完全的代码,前面会对它举行具体的申明:

  1. //:CodePackager.java
  2. //"Packs"and"unpacks"thecodein"Thinking
  3. //inJava"forcross-platformdistribution.
  4. /*CommentedsoCodePackagerseesitandstarts
  5. anewchapterdirectory,butsoyoudont
  6. havetoworryaboutthedirectorywherethis
  7. programlives:
  8. packagec17;
  9. */
  10. importjava.util.*;
  11. importjava.io.*;
  12. classPr{
  13. staticvoiderror(Stringe){
  14. System.err.println("ERROR:"+e);
  15. System.exit(1);
  16. }
  17. }
  18. classIO{
  19. staticBufferedReaderdisOpen(Filef){
  20. BufferedReaderin=null;
  21. try{
  22. in=newBufferedReader(
  23. newFileReader(f));
  24. }catch(IOExceptione){
  25. Pr.error("couldnotopen"+f);
  26. }
  27. returnin;
  28. }
  29. staticBufferedReaderdisOpen(Stringfname){
  30. returndisOpen(newFile(fname));
  31. }
  32. staticDataOutputStreamdosOpen(Filef){
  33. DataOutputStreamin=null;
  34. try{
  35. in=newDataOutputStream(
  36. newBufferedOutputStream(
  37. newFileOutputStream(f)));
  38. }catch(IOExceptione){
  39. Pr.error("couldnotopen"+f);
  40. }
  41. returnin;
  42. }
  43. staticDataOutputStreamdosOpen(Stringfname){
  44. returndosOpen(newFile(fname));
  45. }
  46. staticPrintWriterpsOpen(Filef){
  47. PrintWriterin=null;
  48. try{
  49. in=newPrintWriter(
  50. newBufferedWriter(
  51. newFileWriter(f)));
  52. }catch(IOExceptione){
  53. Pr.error("couldnotopen"+f);
  54. }
  55. returnin;
  56. }
  57. staticPrintWriterpsOpen(Stringfname){
  58. returnpsOpen(newFile(fname));
  59. }
  60. staticvoidclose(Writeros){
  61. try{
  62. os.close();
  63. }catch(IOExceptione){
  64. Pr.error("closing"+os);
  65. }
  66. }
  67. staticvoidclose(DataOutputStreamos){
  68. try{
  69. os.close();
  70. }catch(IOExceptione){
  71. Pr.error("closing"+os);
  72. }
  73. }
  74. staticvoidclose(Readeros){
  75. try{
  76. os.close();
  77. }catch(IOExceptione){
  78. Pr.error("closing"+os);
  79. }
  80. }
  81. }
  82. classSourceCodeFile{
  83. publicstaticfinalString
  84. startMarker="//:",//Startofsourcefile
  85. endMarker="}///:~",//Endofsource
  86. endMarker2="};///:~",//C++fileend
  87. beginContinue="}///:Continued",
  88. endContinue="///:Continuing",
  89. packMarker="###",//Packedfileheadertag
  90. eol=//Lineseparatoroncurrentsystem
  91. System.getProperty("line.separator"),
  92. filesep=//Systemsfilepathseparator
  93. System.getProperty("file.separator");
  94. publicstaticStringcopyright="";
  95. static{
  96. try{
  97. BufferedReadercr=
  98. newBufferedReader(
  99. newFileReader("Copyright.txt"));
  100. Stringcrin;
  101. while((crin=cr.readLine())!=null)
  102. copyright+=crin+"
  103. ";
  104. cr.close();
  105. }catch(Exceptione){
  106. copyright="";
  107. }
  108. }
  109. privateStringfilename,dirname,
  110. contents=newString();
  111. privatestaticStringchapter="c02";
  112. //Thefilenameseparatorfromtheoldsystem:
  113. publicstaticStringoldsep;
  114. publicStringtoString(){
  115. returndirname+filesep+filename;
  116. }
  117. //Constructorforparsingfromdocumentfile:
  118. publicSourceCodeFile(StringfirstLine,
  119. BufferedReaderin){
  120. dirname=chapter;
  121. //Skippastmarker:
  122. filename=firstLine.substring(
  123. startMarker.length()).trim();
  124. //Findspacethatterminatesfilename:
  125. if(filename.indexOf()!=-1)
  126. filename=filename.substring(
  127. 0,filename.indexOf());
  128. System.out.println("found:"+filename);
  129. contents=firstLine+eol;
  130. if(copyright.length()!=0)
  131. contents+=copyright+eol;
  132. Strings;
  133. booleanfoundEndMarker=false;
  134. try{
  135. while((s=in.readLine())!=null){
  136. if(s.startsWith(startMarker))
  137. Pr.error("Noendoffilemarkerfor"+
  138. filename);
  139. //Forthisprogram,nospacesbefore
  140. //the"package"keywordareallowed
  141. //intheinputsourcecode:
  142. elseif(s.startsWith("package")){
  143. //Extractpackagename:
  144. Stringpdir=s.substring(
  145. s.indexOf()).trim();
  146. pdir=pdir.substring(
  147. 0,pdir.indexOf(;)).trim();
  148. //Capturethechapterfromthepackage
  149. //ignoringthecomsubdirectories:
  150. if(!pdir.startsWith("com")){
  151. intfirstDot=pdir.indexOf(.);
  152. if(firstDot!=-1)
  153. chapter=
  154. pdir.substring(0,firstDot);
  155. else
  156. chapter=pdir;
  157. }
  158. //Convertpackagenametopathname:
  159. pdir=pdir.replace(
  160. .,filesep.charAt(0));
  161. System.out.println("package"+pdir);
  162. dirname=pdir;
  163. }
  164. contents+=s+eol;
  165. //Movepastcontinuations:
  166. if(s.startsWith(beginContinue))
  167. while((s=in.readLine())!=null)
  168. if(s.startsWith(endContinue)){
  169. contents+=s+eol;
  170. break;
  171. }
  172. //Watchforendofcodelisting:
  173. if(s.startsWith(endMarker)||
  174. s.startsWith(endMarker2)){
  175. foundEndMarker=true;
  176. break;
  177. }
  178. }
  179. if(!foundEndMarker)
  180. Pr.error(
  181. "EndmarkernotfoundbeforeEOF");
  182. System.out.println("Chapter:"+chapter);
  183. }catch(IOExceptione){
  184. Pr.error("Errorreadingline");
  185. }
  186. }
  187. //Forrecoveringfromapackedfile:
  188. publicSourceCodeFile(BufferedReaderpFile){
  189. try{
  190. Strings=pFile.readLine();
  191. if(s==null)return;
  192. if(!s.startsWith(packMarker))
  193. Pr.error("Cantfind"+packMarker
  194. +"in"+s);
  195. s=s.substring(
  196. packMarker.length()).trim();
  197. dirname=s.substring(0,s.indexOf(#));
  198. filename=s.substring(s.indexOf(#)+1);
  199. dirname=dirname.replace(
  200. oldsep.charAt(0),filesep.charAt(0));
  201. filename=filename.replace(
  202. oldsep.charAt(0),filesep.charAt(0));
  203. System.out.println("listing:"+dirname
  204. +filesep+filename);
  205. while((s=pFile.readLine())!=null){
  206. //Watchforendofcodelisting:
  207. if(s.startsWith(endMarker)||
  208. s.startsWith(endMarker2)){
  209. contents+=s;
  210. break;
  211. }
  212. contents+=s+eol;
  213. }
  214. }catch(IOExceptione){
  215. System.err.println("Errorreadingline");
  216. }
  217. }
  218. publicbooleanhasFile(){
  219. returnfilename!=null;
  220. }
  221. publicStringdirectory(){returndirname;}
  222. publicStringfilename(){returnfilename;}
  223. publicStringcontents(){returncontents;}
  224. //Towritetoapackedfile:
  225. publicvoidwritePacked(DataOutputStreamout){
  226. try{
  227. out.writeBytes(
  228. packMarker+dirname+"#"
  229. +filename+eol);
  230. out.writeBytes(contents);
  231. }catch(IOExceptione){
  232. Pr.error("writing"+dirname+
  233. filesep+filename);
  234. }
  235. }
  236. //Togeneratetheactualfile:
  237. publicvoidwriteFile(Stringrootpath){
  238. Filepath=newFile(rootpath,dirname);
  239. path.mkdirs();
  240. PrintWriterp=
  241. IO.psOpen(newFile(path,filename));
  242. p.print(contents);
  243. IO.close(p);
  244. }
  245. }
  246. classDirMap{
  247. privateHashtablet=newHashtable();
  248. privateStringrootpath;
  249. DirMap(){
  250. rootpath=System.getProperty("user.dir");
  251. }
  252. DirMap(StringalternateDir){
  253. rootpath=alternateDir;
  254. }
  255. publicvoidadd(SourceCodeFilef){
  256. Stringpath=f.directory();
  257. if(!t.containsKey(path))
  258. t.put(path,newVector());
  259. ((Vector)t.get(path)).addElement(f);
  260. }
  261. publicvoidwritePackedFile(Stringfname){
  262. DataOutputStreampacked=IO.dosOpen(fname);
  263. try{
  264. packed.writeBytes("###OldSeparator:"+
  265. SourceCodeFile.filesep+"###
  266. ");
  267. }catch(IOExceptione){
  268. Pr.error("Writingseparatorto"+fname);
  269. }
  270. Enumeratione=t.keys();
  271. while(e.hasMoreElements()){
  272. Stringdir=(String)e.nextElement();
  273. System.out.println(
  274. "Writingdirectory"+dir);
  275. Vectorv=(Vector)t.get(dir);
  276. for(inti=0;i<v.size();i++){
  277. SourceCodeFilef=
  278. (SourceCodeFile)v.elementAt(i);
  279. f.writePacked(packed);
  280. }
  281. }
  282. IO.close(packed);
  283. }
  284. //Writeallthefilesintheirdirectories:
  285. publicvoidwrite(){
  286. Enumeratione=t.keys();
  287. while(e.hasMoreElements()){
  288. Stringdir=(String)e.nextElement();
  289. Vectorv=(Vector)t.get(dir);
  290. for(inti=0;i<v.size();i++){
  291. SourceCodeFilef=
  292. (SourceCodeFile)v.elementAt(i);
  293. f.writeFile(rootpath);
  294. }
  295. //Addfileindicatingfilequantity
  296. //writtentothisdirectoryasacheck:
  297. IO.close(IO.dosOpen(
  298. newFile(newFile(rootpath,dir),
  299. Integer.toString(v.size())+".files")));
  300. }
  301. }
  302. }
  303. publicclassCodePackager{
  304. privatestaticfinalStringusageString=
  305. "usage:javaCodePackagerpackedFileName"+
  306. "
  307. Extractssourcecodefilesfrompacked
  308. "+
  309. "versionofTjava.docsourcesinto"+
  310. "directoriesoffcurrentdirectory
  311. "+
  312. "javaCodePackagerpackedFileNamenewDir
  313. "+
  314. "ExtractsintodirectoriesoffnewDir
  315. "+
  316. "javaCodePackager-psource.txtpackedFile"+
  317. "
  318. Createspackedversionofsourcefiles"+
  319. "
  320. fromtextversionofTjava.doc";
  321. privatestaticvoidusage(){
  322. System.err.println(usageString);
  323. System.exit(1);
  324. }
  325. publicstaticvoidmain(String[]args){
  326. if(args.length==0)usage();
  327. if(args[0].equals("-p")){
  328. if(args.length!=3)
  329. usage();
  330. createPackedFile(args);
  331. }
  332. else{
  333. if(args.length>2)
  334. usage();
  335. extractPackedFile(args);
  336. }
  337. }
  338. privatestaticStringcurrentLine;
  339. privatestaticBufferedReaderin;
  340. privatestaticDirMapdm;
  341. privatestaticvoid
  342. createPackedFile(String[]args){
  343. dm=newDirMap();
  344. in=IO.disOpen(args[1]);
  345. try{
  346. while((currentLine=in.readLine())
  347. !=null){
  348. if(currentLine.startsWith(
  349. SourceCodeFile.startMarker)){
  350. dm.add(newSourceCodeFile(
  351. currentLine,in));
  352. }
  353. elseif(currentLine.startsWith(
  354. SourceCodeFile.endMarker))
  355. Pr.error("filehasnostartmarker");
  356. //Elseignoretheinputline
  357. }
  358. }catch(IOExceptione){
  359. Pr.error("Errorreading"+args[1]);
  360. }
  361. IO.close(in);
  362. dm.writePackedFile(args[2]);
  363. }
  364. privatestaticvoid
  365. extractPackedFile(String[]args){
  366. if(args.length==2)//Alternatedirectory
  367. dm=newDirMap(args[1]);
  368. else//Currentdirectory
  369. dm=newDirMap();
  370. in=IO.disOpen(args[0]);
  371. Strings=null;
  372. try{
  373. s=in.readLine();
  374. }catch(IOExceptione){
  375. Pr.error("Cannotreadfrom"+in);
  376. }
  377. //Capturetheseparatorusedinthesystem
  378. //thatpackedthefile:
  379. if(s.indexOf("###OldSeparator:")!=-1){
  380. Stringoldsep=s.substring(
  381. "###OldSeparator:".length());
  382. oldsep=oldsep.substring(
  383. 0,oldsep.indexOf(#));
  384. SourceCodeFile.oldsep=oldsep;
  385. }
  386. SourceCodeFilesf=newSourceCodeFile(in);
  387. while(sf.hasFile()){
  388. dm.add(sf);
  389. sf=newSourceCodeFile(in);
  390. }
  391. dm.write();
  392. }
  393. }///:~
复制代码
我们注重到package语句已作为正文标记出来了。因为这是本章的第一个程序,以是package语句是必须的,用它告知CodePackager已更换到另外一章。可是把它放进包里却会成为一个成绩。当我们创立一个包的时分,必要将了局程序统一个特定的目次布局接洽在一同,这一做法对本书的年夜多半例子都是合用的。但在这里,CodePackager程序必需在一个公用的目次里编译和运转,以是package语句作为正文标志进来。但对CodePackager来讲,它“看起来”仍然象一个一般的package语句,由于程序还不是出格庞大,不克不及侦察到多行正文(没有需要做得这么庞大,这里只需求便利就行)。
头两个类是“撑持/工具”类,感化是使程序残剩的部分在编写时加倍联贯,也更便于浏览。第一个是Pr,它相似ANSIC的perror库,二者都能打印出一条毛病提醒动静(但同时也会加入程序)。第二个类将文件的创立历程封装在内,这个历程已在第10章先容过了;人人已晓得,如许做很快就会变得十分包袱和贫苦。为办理这个成绩,第10章供应的计划努力于新类的创立,但这儿的“静态”办法已利用过了。在那些办法中,一般的背例会被捕捉,并响应地举行处置。这些办法使残剩的代码显得加倍清新,更容易浏览。
匡助办理成绩的第一个类是SourceCodeFile(源码文件),它代表本书一个源码文件包括的一切信息(内容、文件名和目次)。它同时还包括了一系列String常数,分离代表一个文件的入手下手与停止;在打包文件内利用的一个标志;以后体系的换行符;文件路径分开符(注重要用System.getProperty()侦察当地版本是甚么);和一年夜段版权声明,它是从上面这个Copyright.txt文件里提掏出来的:
  1. //////////////////////////////////////////////////
  2. //Copyright(c)BruceEckel,1998
  3. //Sourcecodefilefromthebook"ThinkinginJava"
  4. //AllrightsreservedEXCEPTasallowedbythe
  5. //followingstatements:Youmayfreelyusethisfile
  6. //foryourownwork(personalorcommercial),
  7. //includingmodificationsanddistributionin
  8. //executableformonly.Permissionisgrantedtouse
  9. //thisfileinclassroomsituations,includingits
  10. //useinpresentationmaterials,aslongasthebook
  11. //"ThinkinginJava"iscitedasthesource.
  12. //Exceptinclassroomsituations,youmaynotcopy
  13. //anddistributethiscode;instead,thesole
  14. //distributionpointishttp://www.BruceEckel.com
  15. //(andofficialmirrorsites)whereitis
  16. //freelyavailable.Youmaynotremovethis
  17. //copyrightandnotice.Youmaynotdistribute
  18. //modifiedversionsofthesourcecodeinthis
  19. //package.Youmaynotusethisfileinprinted
  20. //mediawithouttheexpresspermissionofthe
  21. //author.BruceEckelmakesnorepresentationabout
  22. //thesuitabilityofthissoftwareforanypurpose.
  23. //Itisprovided"asis"withoutexpressorimplied
  24. //warrantyofanykind,includinganyimplied
  25. //warrantyofmerchantability,fitnessfora
  26. //particularpurposeornon-infringement.Theentire
  27. //riskastothequalityandperformanceofthe
  28. //softwareiswithyou.BruceEckelandthe
  29. //publishershallnotbeliableforanydamages
  30. //sufferedbyyouoranythirdpartyasaresultof
  31. //usingordistributingsoftware.Innoeventwill
  32. //BruceEckelorthepublisherbeliableforany
  33. //lostrevenue,profit,ordata,orfordirect,
  34. //indirect,special,consequential,incidental,or
  35. //punitivedamages,howevercausedandregardlessof
  36. //thetheoryofliability,arisingoutoftheuseof
  37. //orinabilitytousesoftware,evenifBruceEckel
  38. //andthepublisherhavebeenadvisedofthe
  39. //possibilityofsuchdamages.Shouldthesoftware
  40. //provedefective,youassumethecostofall
  41. //necessaryservicing,repair,orcorrection.Ifyou
  42. //thinkyouvefoundanerror,pleaseemailall
  43. //modifiedfileswithclearlycommentedchangesto:
  44. //Bruce@EckelObjects.com.(pleaseusethesame
  45. //addressfornon-codeerrorsfoundinthebook).
  46. //////////////////////////////////////////////////
复制代码
从一个打包文件中提取文件时,现在所用体系的文件分开符也会标注出来,以便用当地体系合用的标记交换它。
以后章的子目次保留在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来展现。
兰色精灵 该用户已被删除
沙发
发表于 2015-1-26 14:42:14 | 只看该作者
任职于太阳微系统的詹姆斯·高斯林等人于1990年代初开发Java语言的雏形,最初被命名为Oak,目标设置在家用电器等小型系统的程序语言
柔情似水 该用户已被删除
板凳
发表于 2015-1-28 06:05:59 | 只看该作者
Java是一种计算机编程语言,拥有跨平台、面向对java
只想知道 该用户已被删除
地板
发表于 2015-1-30 20:53:02 来自手机 | 只看该作者
Sun公司看见Oak在互联网上应用的前景,于是改造了Oak,于1995年5月以Java的名称正式发布。Java伴随着互联网的迅猛发展而发展,逐渐成为重要的网络编程语言。
小妖女 该用户已被删除
5#
发表于 2015-1-31 09:05:21 | 只看该作者
设计模式是高级程序员真正掌握面向对象核心思想的必修课。设计模式并不是一种具体"技术",它讲述的是思想,它不仅仅展示了接口或抽象类在实际案例中的灵活应用和智慧
冷月葬花魂 该用户已被删除
6#
发表于 2015-2-6 18:54:25 | 只看该作者
J2SE开发桌面应用软件比起 VC,VB,DEPHI这些传统开发语言来说,优势好象并不明显。J2ME对于初学者来说,好象又有点深奥,而且一般开发者很难有开发环境。
爱飞 该用户已被删除
7#
发表于 2015-2-10 07:08:43 | 只看该作者
接着就是EJB了,EJB就是Enterprise JavaBean, 看名字好象它是Javabean,可是它和Javabean还是有区别的。它是一个体系结构,你可以搭建更安全、更稳定的企业应用。它的大量代码已由中间件(也就是我们常听到的 Weblogic,Websphere这些J2EE服务器)完成了,所以我们要做的程序代码量很少,大部分工作都在设计和配置中间件上。
简单生活 该用户已被删除
8#
发表于 2015-3-1 01:31:46 | 只看该作者
学Java必读的两个开源程序就是Jive和Pet Store.。 Jive是国外一个非常著名的BBS程序,完全开放源码。论坛的设计采用了很多先进的技术,如Cache、用户认证、Filter、XML等,而且论坛完全屏蔽了对数据库的访问,可以很轻易的在不同数据库中移植。论坛还有方便的安装和管理程序,这是我们平时编程时容易忽略的一部份(中国程序员一般只注重编程的技术含量,却完全不考虑用户的感受,这就是我们与国外软件的差距所在)。
9#
发表于 2015-3-5 05:23:26 | 只看该作者
是一种语言,用以产生「小应用程序(Applet(s))
再现理想 该用户已被删除
10#
发表于 2015-3-6 11:10:11 | 只看该作者
你一定会高兴地说,哈哈,原来成为Java高手就这么简单啊!记得Tomjava也曾碰到过一个项目经理,号称Java很简单,只要三个月就可以学会。
山那边是海 该用户已被删除
11#
发表于 2015-3-11 05:36:16 | 只看该作者
是一种使用者不需花费很多时间学习的语言
深爱那片海 该用户已被删除
12#
发表于 2015-3-15 20:59:14 | 只看该作者
是一种突破用户端机器环境和CPU
再见西城 该用户已被删除
13#
发表于 2015-3-18 19:40:49 | 只看该作者
关于设计模式的资料,还是向大家推荐banq的网站 [url]http://www.jdon.com/[/url],他把GOF的23种模式以通俗易懂的方式诠释出来,纯Java描述,真是经典中的经典。
飘飘悠悠 该用户已被删除
14#
发表于 2015-3-26 12:30:00 | 只看该作者
你现在最缺的是实际的工作经验,而不是书本上那些凭空想出来的程序。
金色的骷髅 该用户已被删除
15#
发表于 2015-3-27 09:09:45 | 只看该作者
《JAVA语言程序设计》或《JAVA从入门到精通》这两本书开始学,等你编程有感觉的时候也可以回看一下。《JAVA读书笔记》这本书,因为讲的代码很多,也很容易看懂,涉及到面也到位。是你学习技术巩固的好书,学完后就看看《JAVA编程思想》这本书,找找一个自己写的代码跟书上的代码有什么不一样。
精灵巫婆 该用户已被删除
16#
发表于 2015-3-27 16:09:40 | 只看该作者
另外编写和运行Java程序需要JDK(包括JRE),在sun的官方网站上有下载,thinking in java第三版用的JDK版本是1.4,现在流行的版本1.5(sun称作J2SE 5.0,汗),不过听说Bruce的TIJ第四版国外已经出来了,是专门为J2SE 5.0而写的。
变相怪杰 该用户已被删除
17#
发表于 2015-3-30 09:30:40 | 只看该作者
接着就是EJB了,EJB就是Enterprise JavaBean, 看名字好象它是Javabean,可是它和Javabean还是有区别的。它是一个体系结构,你可以搭建更安全、更稳定的企业应用。它的大量代码已由中间件(也就是我们常听到的 Weblogic,Websphere这些J2EE服务器)完成了,所以我们要做的程序代码量很少,大部分工作都在设计和配置中间件上。
因胸联盟 该用户已被删除
18#
发表于 2015-4-14 00:29:08 | 只看该作者
设计模式是高级程序员真正掌握面向对象核心思想的必修课。设计模式并不是一种具体"技术",它讲述的是思想,它不仅仅展示了接口或抽象类在实际案例中的灵活应用和智慧
海妖 该用户已被删除
19#
发表于 2015-4-27 11:16:44 | 只看该作者
当然你也可以参加一些开源项目,一方面可以提高自己,另一方面也是为中国软件事业做贡献嘛!开发者在互联网上用CVS合作开发,用QQ,MSN,E-mail讨论联系,天南海北的程序员分散在各地却同时开发同一个软件,是不是很有意思呢?
若天明 该用户已被删除
20#
发表于 2015-5-6 11:09:38 | 只看该作者
不过,每次的执行编译后的字节码需要消耗一定的时间,这同时也在一定程度上降低了 Java 程序的运行效率。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2024-12-23 02:39

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表