Java编程思想第4版[中文版](PDF格式)-第80部分
按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
//: DirList3。java
// Building the anonymous inner class 〃in…place〃
import java。io。*;
public class DirList3 {
public static void main(final String'' args) {
try {
File path = new File(〃。〃);
String'' list;
if(args。length == 0)
list = path。list();
else
list = path。list(
new FilenameFilter() {
public boolean
accept(File dir; String n) {
String f = new File(n)。getName();
290
…………………………………………………………Page 292……………………………………………………………
return f。indexOf(args'0') != …1;
}
});
for(int i = 0; i 《 list。length; i++)
System。out。println(list'i');
} catch(Exception e) {
e。printStackTrace();
}
}
} ///:~
main()现在的自变量是 final,因为匿名内部类直接使用args'0'。
这展示了如何利用匿名内部类快速创建精简的类,以便解决一些复杂的问题。由于Java 中的所有东西都与类
有关,所以它无疑是一种相当有用的编码技术。它的一个好处是将特定的问题隔离在一个地方统一解决。但
在另一方面,这样生成的代码不是十分容易阅读,所以使用时必须慎重。
2。 顺序目录列表
经常都需要文件名以排好序的方式提供。由于 Java 1。0 和Java 1。1 都没有提供对排序的支持(从 Java 1。2
开始提供),所以必须用第8 章创建的 SortVector将这一能力直接加入自己的程序。就象下面这样:
//: SortedDirList。java
// Displays sorted directory listing
import java。io。*;
import c08。*;
public class SortedDirList {
private File path;
private String'' list;
public SortedDirList(final String afn) {
path = new File(〃。〃);
if(afn == null)
list = path。list();
else
list = path。list(
new FilenameFilter() {
public boolean
accept(File dir; String n) {
String f = new File(n)。getName();
return f。indexOf(afn) != …1;
}
});
sort();
}
void print() {
for(int i = 0; i 《 list。length; i++)
System。out。println(list'i');
}
private void sort() {
StrSortVector sv = new StrSortVector();
for(int i = 0; i 《 list。length; i++)
sv。addElement(list'i');
// The first time an element is pulled from
291
…………………………………………………………Page 293……………………………………………………………
// the StrSortVector the list is sorted:
for(int i = 0; i 《 list。length; i++)
list'i' = sv。elementAt(i);
}
// Test it:
public static void main(String'' args) {
SortedDirList sd;
if(args。length == 0)
sd = new SortedDirList(null);
else
sd = new SortedDirList(args'0');
sd。print();
}
} ///:~
这里进行了另外少许改进。不再是将path (路径)和list (列表)创建为main()的本地变量,它们变成了
类的成员,使它们的值能在对象“生存”期间方便地访问。事实上,main()现在只是对类进行测试的一种方
式。大家可以看到,一旦列表创建完毕,类的构建器就会自动开始对列表进行排序。
这种排序不要求区分大小写,所以最终不会得到一组全部单词都以大写字母开头的列表,跟着是全部以小写
字母开头的列表。然而,我们注意到在以相同字母开头的一组文件名中,大写字母是排在前面的——这对标
准的排序来说仍是一种不合格的行为。Java 1。2 已成功解决了这个问题。
10。4。2 检查与创建目录
File 类并不仅仅是对现有目录路径、文件或者文件组的一个表示。亦可用一个 File 对象新建一个目录,甚
至创建一个完整的目录路径——假如它尚不存在的话。亦可用它了解文件的属性(长度、上一次修改日期、
读/写属性等),检查一个File 对象到底代表一个文件还是一个目录,以及删除一个文件等等。下列程序完
整展示了如何运用 File 类剩下的这些方法:
//: MakeDirectories。java
// Demonstrates the use of the File class to
// create directories and manipulate files。
import java。io。*;
public class MakeDirectories {
private final static String usage =
〃Usage:MakeDirectories path1 。。。 n〃 +
〃Creates each pathn〃 +
〃Usage:MakeDirectories …d path1 。。。n〃 +
〃Deletes each pathn〃 +
〃Usage:MakeDirectories …r path1 path2n〃 +
〃Renames from path1 to path2n〃;
private static void usage() {
System。err。println(usage);
System。exit(1);
}
private static void fileData(File f) {
System。out。println(
〃Absolute path: 〃 + f。getAbsolutePath() +
〃n Can read: 〃 + f。canRead() +
〃n Can write: 〃 + f。canWrite() +
〃n getName: 〃 + f。getName() +
〃n getParent: 〃 + f。getParent() +
292
…………………………………………………………Page 294……………………………………………………………
〃n getPath: 〃 + f。getPath() +
〃n length: 〃 + f。length() +
〃n lastModified: 〃 + f。lastModified());
if(f。isFile())
System。out。println(〃it's a file〃);
else if(f。isDirectory())
System。out。println(〃it's a directory〃);
}
public static void main(String'' args) {
if(args。length 《 1) usage();
if(args'0'。equals(〃…r〃)) {
if(args。length != 3) usage();
File
old = new File(args'1');
rname = new File(args'2');
old。renameTo(rname);
fileData(old);
fileData(rname);
return; // Exit main
}
int count = 0;
boolean del = false;
if(args'0'。equals(〃…d〃)) {
count++;
del = true;
}
for( ; count 《 args。length; count++) {
File f = new File(args'count');
if(f。exists()) {
System。out。println(f + 〃 exists〃);
if(del) {
System。out。println(〃deleting。。。〃 + f);
f。delete();
}
}
else { // Doesn't exist
if(!del) {
f。mkdirs();
System。out。println(〃created 〃 + f);
}
}
fileData(f);
}
}
} ///:~
在 fileData()中,可看到应用了各种文件调查方法来显示与文件或目录路径有关的信息。
main()应用的第一个方法是 renameTo(),利用它可以重命名(或移动)一个文件至一个全新的路径(该路径
由参数决定),它属于另一个File 对象。这也适用于任何长度的目录。
若试验上述程序,就可发现自己能制作任意复杂程度的一个目录路径,因为mkdirs() 会帮我们完成所有工
作。在 Java 1。0 中,…d 标志报告目录虽然已被删除,但它依然存在;但在 Java 1。1 中,目录会被实际删
除。
293
…………………………………………………………Page 295……………………………………………………………
10。5 IO 流的典型应用
尽管库内存在大量 IO 流类,可通过多种不同的方式组合到一起,但实际上只有几种方式才会经常用到。然
而,必须小心在意才能得到正确的组合。下面这个相当长的例子展示了典型 IO 配置的创建与使用,可在写自
己的代码时将其作为一个参考使用。注意每个配置都以一个注释形式的编号起头,并提供了适当的解释信
息。
//: IOStreamDemo。java
// Typical IO Stream Configurations
import java。io。*;
import 。bruceeckel。tools。*;
public class IOStreamDemo {
public static void main(String'' args) {
try {
// 1。 Buffered input file
DataInputStream in =
new DataInputStream(
new BufferedInputStream(
new FileInputStream(args'0')));
String s; s2 = new String();
while((s = in。readLine())!= null)
s2 += s + 〃n〃;
in。close();
// 2。 Input from memory
StringBufferInputStream in2 =
new StringBufferInputStream(s2);
int c;
while((c = in2。read()) != …1)
System。out。print((char)c);
// 3。 Formatted memory input
try {
DataInputStream in3 =
new DataInputStream(
new StringBufferInputStream(s2));
while(true)
System。out。print((char)in3。readByte());
} catch(EOFException e) {
System。out。println(
〃End of stream encountered〃);
}
// 4。 Line numbering & file output
try {
LineNumberInputStream li =
new LineNumberInputStream(
new StringBufferInputStream(s2));
DataInputStream in4 =
new DataInputStream(li);
PrintStream out1 =
new PrintStream(
294
…………………………………………………………Page 296……………………………………………………………
new BufferedOutputStream(
new FileOutputStream(
〃IODemo。out〃)));
while((s = in4。readLine()) != null )
out1。println(
〃Line 〃 + li。getLineNumber() + s);
out1。close(); // finalize() not reliable!
} catch(EOFException e) {
System。out。println(
〃End of stream encountered〃);
}
// 5。 Storing & recovering data
try {
DataOutputStream out2 =
new DataOutputStream(
new BufferedOutputStream(
new FileOutputStream(〃Data。txt〃)));
out2。writeBytes(
〃Here's the value of pi: n〃);
out2。writeDouble(3。14159);
out2。close();
DataInputStream in5 =
new DataInputStream(
new BufferedInputStream(
new FileInputStream(〃Data。txt〃)));
System。out。println(in5。readLine());
System。out。println(in5。readDouble());
} catch(EOFException e) {
System。out。println(
〃End of stream encountered〃);