友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!
Java编程思想第4版[中文版](PDF格式)-第107部分
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部! 如果本书没有阅读完,想下次继续接着阅读,可使用上方 "收藏到我的浏览器" 功能 和 "加入书签" 功能!
Pr。error(〃could not open 〃 + f);
}
return in;
}
static BufferedReader disOpen(String fname) {
return disOpen(new File(fname));
}
static DataOutputStream dosOpen(File f) {
DataOutputStream in = null;
try {
in = new DataOutputStream(
new BufferedOutputStream(
new FileOutputStream(f)));
} catch(IOException e) {
Pr。error(〃could not open 〃 + f);
}
return in;
}
static DataOutputStream dosOpen(String fname) {
return dosOpen(new File(fname));
}
static PrintWriter psOpen(File f) {
PrintWriter in = null;
try {
in = new PrintWriter(
new BufferedWriter(
new FileWriter(f)));
} catch(IOException e) {
Pr。error(〃could not open 〃 + f);
623
…………………………………………………………Page 625……………………………………………………………
}
return in;
}
static PrintWriter psOpen(String fname) {
return psOpen(new File(fname));
}
static void close(Writer os) {
try {
os。close();
} catch(IOException e) {
Pr。error(〃closing 〃 + os);
}
}
static void close(DataOutputStream os) {
try {
os。close();
} catch(IOException e) {
Pr。error(〃closing 〃 + os);
}
}
static void close(Reader os) {
try {
os。close();
} catch(IOException e) {
Pr。error(〃closing 〃 + os);
}
}
}
class SourceCodeFile {
public static final String
startMarker = 〃//:〃; // Start of source file
endMarker = 〃} ///:~〃; // End of source
endMarker2 = 〃}; ///:~〃; // C++ file end
beginContinue = 〃} ///:Continued〃;
endContinue = 〃///:Continuing〃;
packMarker = 〃###〃; // Packed file header tag
eol = // Line separator on current system
System。getProperty(〃line。separator〃);
filesep = // System's file path separator
System。getProperty(〃file。separator〃);
public static String copyright = 〃〃;
static {
try {
BufferedReader cr =
new BufferedReader(
new FileReader(〃Copyright。txt〃));
String crin;
while((crin = cr。readLine()) != null)
copyright += crin + 〃n〃;
cr。close();
} catch(Exception e) {
624
…………………………………………………………Page 626……………………………………………………………
copyright = 〃〃;
}
}
private String filename; dirname;
contents = new String();
private static String chapter = 〃c02〃;
// The file name separator from the old system:
public static String oldsep;
public String toString() {
return dirname + filesep + filename;
}
// Constructor for parsing from document file:
public SourceCodeFile(String firstLine;
BufferedReader in) {
dirname = chapter;
// Skip past marker:
filename = firstLine。substring(
startMarker。length())。trim();
// Find space that terminates file name:
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;
String s;
boolean foundEndMarker = false;
try {
while((s = in。readLine()) != null) {
if(s。startsWith(startMarker))
Pr。error(〃No end of file marker for 〃 +
filename);
// For this program; no spaces before
// the 〃package〃 keyword are allowed
// in the input source code:
else if(s。startsWith(〃package〃)) {
// Extract package name:
String pdir = s。substring(
s。indexOf(' '))。trim();
pdir = pdir。substring(
0; pdir。indexOf(';'))。trim();
// Capture the chapter from the package
// ignoring the '' subdirectories:
if(!pdir。startsWith(〃〃)) {
int firstDot = pdir。indexOf('。');
if(firstDot != …1)
chapter =
pdir。substring(0;firstDot);
else
chapter = pdir;
}
625
…………………………………………………………Page 627……………………………………………………………
// Convert package name to path name:
pdir = pdir。replace(
'。'; filesep。charAt(0));
System。out。println(〃package 〃 + pdir);
dirname = pdir;
}
contents += s + eol;
// Move past continuations:
if(s。startsWith(beginContinue))
while((s = in。readLine()) != null)
if(s。startsWith(endContinue)) {
contents += s + eol;
break;
}
// Watch for end of code listing:
if(s。startsWith(endMarker) ||
s。startsWith(endMarker2)) {
foundEndMarker = true;
break;
}
}
if(!foundEndMarker)
Pr。error(
〃End marker not found before EOF〃);
System。out。println(〃Chapter: 〃 + chapter);
} catch(IOException e) {
Pr。error(〃Error reading line〃);
}
}
// For recovering from a packed file:
public SourceCodeFile(BufferedReader pFile) {
try {
String s = pFile。readLine();
if(s == null) return;
if(!s。startsWith(packMarker))
Pr。error(〃Can't find 〃 + 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(〃l isting: 〃 + dirname
+ filesep + filename);
while((s = pFile。readLine()) != null) {
// Watch for end of code listing:
if(s。startsWith(endMarker) ||
s。startsWith(endMarker2)) {
contents += s;
626
…………………………………………………………Page 628……………………………………………………………
break;
}
contents += s + eol;
}
} catch(IOException e) {
System。err。println(〃Error reading line〃);
}
}
public boolean hasFile() {
return filename != null;
}
public String directory() { return dirname; }
public String filename() { return filename; }
public String contents() { return contents; }
// To write to a packed file:
public void writePacked(DataOutputStream out) {
try {
out。writeBytes(
packMarker + dirname + 〃#〃
+ filename + eol);
out。writeBytes(contents);
} catch(IOException e) {
Pr。error(〃writing 〃 + dirname +
filesep + filename);
}
}
// To generate the actual file:
public void writeFile(String rootpath) {
File path = new File(rootpath; dirname);
path。mkdirs();
PrintWriter p =
IO。psOpen(new File(path; filename));
p。print(contents);
IO。close(p);
}
}
class DirMap {
private Hashtable t = new Hashtable();
private String rootpath;
DirMap() {
rootpath = System。getProperty(〃user。dir〃);
}
DirMap(String alternateDir) {
rootpath = alternateDir;
}
public void add(SourceCodeFile f){
String path = f。directory();
if(!t。containsKey(path))
t。put(path; new Vector());
((Vector)t。get(path))。addElement(f);
}
627
…………………………………………………………Page 629……………………………………………………………
public void writePackedFile(String fname) {
DataOutputStream packed = IO。dosOpen(fname);
try {
packed。writeBytes(〃###Old Separator:〃 +
SourceCodeFile。filesep + 〃###n〃);
} catch(IOException e) {
Pr。error(〃Writing separator to 〃 + fname);
}
Enumeration e = t。keys();
while(e。hasMoreElements()) {
String dir = (String)e。nextElement();
System。out。println(
〃Writing directory 〃 + dir);
Vector v = (Vector)t。get(dir);
for(int i = 0; i 《 v。size(); i++) {
SourceCodeFile f =
(SourceCodeFile)v。elementAt(i);
f。writePacked(packed);
}
}
IO。close(packed);
}
// Write all the files in their directories:
public void write() {
Enumeration e = t。keys();
while(e。hasMoreElements()) {
String dir = (String)e。nextElement();
Vector v = (Vector)t。get(dir);
for(int i = 0; i 《 v。size(); i++) {
SourceCodeFile f =
(SourceCodeFile)v。elementAt(i);
f。writeFile(rootpath);
}
// Add file indicating file quantity
// written to this directory as a check:
IO。close(IO。dosOpen(
new File(new File(rootpath; dir);
Integer。toString(v。size())+〃。files〃)));
}
}
}
public class CodePackager {
private static final String usageString =
〃usage: java CodePackager packedFileName〃 +
〃nExtracts source code files from packed n〃 +
〃version of Tjava。doc sources into 〃 +
〃directories off current directory n〃 +
〃java CodePackager packedFileName newDirn〃 +
〃Extracts into directories off newDirn〃 +
〃java CodePackager …p source。txt packedFile〃 +
〃nCreates packed version of source files〃 +
628
…………………………………………………………Page 630……………………………………………………………
〃nfrom text version of Tjava。doc〃;
private static void usage() {
System。err。println(usageString);
System。exit(1);
}
public static void main(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);
}
}
private static String currentLine;
private static BufferedReader in;
private static DirMap dm;
private static void
createPackedFile(String'' args) {
dm = new DirMap();
in = IO。disOpen(args'1');
try {
while((currentLine = in。readLine())
!= null) {
if(currentLine。startsWith(
SourceCodeFile。startMarker)) {
dm。add(new SourceCodeFile(
currentLine; in));
}
else if(currentLine。startsWith(
SourceCodeFile。endMarker))
Pr。error(〃file has no start marker〃);
// Else ignore the input line
}
} catch(IOException e) {
Pr。error(〃Error reading 〃 + args'1');
}
IO。close(in);
dm。writePackedFile(args'2');
}
private static void
extractPackedFile(String'' args) {
if(args。length == 2) // Alternate directory
dm = new DirMap(args'1');
else // Current directory
dm = new DirMap();
in = IO。disOpen(args'0');
String s = null;
629
…………………………………………………………Page 631……………………………………………………………
try {
s = in。readLine();
} catch(IOException e) {
Pr。error(〃Cannot read from 〃 + in);
}
// Capture the separator used in the system
// that packed the file:
if(s。indexOf(〃###Old Separator:〃) != …1 ) {
String oldsep = s。substring(
〃###Old Separator:〃。length());
oldsep = oldsep。substring(
0; oldsep。 indexOf('#'));
SourceCodeFile。oldsep = oldsep;
}
SourceCodeFile sf = new SourceCodeFile(in);
while(sf。hasFile()) {
dm。add(sf);
sf = new SourceCodeFile(in);
}
dm。write();
}
} ///:~
我们注意到 package 语句已经作为注释标志出来了。由于这是本章的第一个程序,所以package 语句是必需
的,用它告诉CodePackager 已改换到另一章。但是把它放入包里却会成为一个问题。当我们创建一个包的时
候,需要将结果程序同一个特定的目录结构联系在一起,这一做法对本书的大多数例子都是适用的。但在这
里,CodePackager 程序必须在一个专用的目录里编译和运行,所以 package 语句作为注释标记出去。但对
CodePackager 来说,它“看起来”依然象一个普通的package 语句,因为程序还不是特别复杂,不能侦查到
多行注释(没有必要做得这么复杂,这里只要求方便就行)。
头两个类是“支持/工具”类,作用是使程序剩余的部分在编写时更加连贯,也更便于阅读。第一个是Pr,
它类似ANSI C 的perror 库,两者都能打印出一条错误提示消息(但同时也会退出程序)。第二个类将文件
的创建过程封装在内,这个过程已在第10章介绍过了;大家已经知道,这样做很快就会变得非常累赘和麻
烦。为解决这个问题,第 10 章提供的方案致力于新类的创建,但这儿的“静态”方法已经使用过了。在那些
方法中,正常的违例会被捕获,并相应地进行处理。这些方法使剩余的代码显得更加清爽,更易阅读。
帮助解决问题的第一个类是SourceCodeFile (源码文件),它代表本书一个源码文件包含的所有信息(内
容、文件名以及目录)。它同时还包含了一系列String 常数,分别代表一个文件的开始与结束;在打包文件
内使用的一个标记;当前系统的换行符;文件路径分隔符(注意要用System。getProperty()侦查本地版本是
什么);以及一大段版权声明,它是从下面这个Copyright。txt 文件里提取出来的:
//////////////////////////////////////////////////
// Copyright (c) Bruce Eckel; 1998
// Source code file from the book 〃Thinking in Java〃
// All rights reserved EXCEPT as allowed by the
// following statements: You may freely use this file
// for your own work (personal or mercial);
// including modifications and distribution in
// executable form only。 Permission is granted to use
// this file in classroom situations; including its
// use in presentation materials; as lon
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!