Filef=newFile(args[count]);
if(f.exists()){
System.out.println(f+"exists");
if(del){
System.out.println("deleting..."+f);
f.delete();
}
}
else{//Doesn'texist
if(!
del){
f.mkdirs();
System.out.println("created"+f);
}
}
fileData(f);
}
if(args.length==1&&
args[0].equals("MakeDirectoriesTest"))
monitor.expect(newString[]{
"%%(MakeDirectoriesTestexists"+
"|createdMakeDirectoriesTest)",
"%%Absolutepath:
"
+"\\S+MakeDirectoriesTest",
"%%Canread:
(true|false)",
"%%Canwrite:
(true|false)",
"getName:
MakeDirectoriesTest",
"getParent:
null",
"getPath:
MakeDirectoriesTest",
"%%length:
\\d+",
"%%lastModified:
\\d+",
"It'sadirectory"
});
}
}///:
~
在fileData()演示了全套查询文件和目录路径信息的方法。
main()的第一条指令就是执行renameTo()。
它会把文件重命名成(或者说移动到)新的目录,也就是参数所给出的目录。
而参数本身就是一个File对象。
这个方法也适用于目录。
如果你试过上面那段程序,就会发现,你能用它创建任意复杂的目录路径,因为mkdirs()已经帮你打理好了。
输入与输出
I/O类库常使用"流(stream)"这种抽象。
所谓"流"是一种能生成或接受数据的,代表数据的源和目标的对象。
流把I/O设备内部的具体操作给隐藏起来了。
正如JDK文档所显示的,Java的I/O类库分成输入和输出两大部分。
所有InputStream和Reader的派生类都有一个基本的,继承下来的,能读取单个或byte数组的read()方法。
同理,所有OutputStream和Writer的派生类都有一个基本的,能写入单个或byte数组的write()方法。
但通常情况下,你是不会去用这些方法的;它们是给其它类用的——而后者会提供一些更实用的接口。
因此,你很少会碰到只用一个类就能创建一个流的情形,实际上你得把多个对象叠起来,并以此来获取所需的功能。
Java的流类库之所以会那么让人犯晕,最主要的原因就是"你必须为创建一个流而动用多个对象"。
我们最好还是根据其功能为这些class归个类。
Java1.0的类库设计者们是从决定"让所有与输入相关的类去继承InputStream"入手的。
同理,所有与输出相关的类就该继承OutputStream了。
添加属性与适用的接口
使用"分层对象(layeredobjects)",为单个对象动态地,透明地添加功能的做法,被称为DecoratorPattern。
(模式[61]是ThinkinginPatterns(withJava)的主题。
)Decorator模式要求所有包覆在原始对象之外的对象,都必须具有与之完全相同的接口。
这使得decorator的用法变得非常的透明--无论对象是否被decorate过,传给它的消息总是相同的。
这也是JavaI/O类库要有"filter(过滤器)"类的原因:
抽象的"filter"类是所有decorator的基类。
(decorator必须具有与它要包装的对象的全部接口,但是decorator可以扩展这个接口,由此就衍生出了很多"filter"类)。
Decorator模式常用于如下的情形:
如果用继承来解决各种需求的话,类的数量会多到不切实际的地步。
Java的I/O类库需要提供很多功能的组合,于是decorator模式就有了用武之地。
[62]但是decorator有个缺点,在提高编程的灵活性的同时(因为你能很容易地混合和匹配属性),也使代码变得更复杂了。
Java的I/O类库之所以会这么怪,就是因为它"必须为一个I/O对象创建很多类",也就是为一个"核心"I/O类加上很多decorator。
为InputStream和OutputStream定义decorator类接口的类,分别是FilterInputStream和FilterOutputStream。
这两个名字都起得不怎么样。
FilterInputStream和FilterOutputStream都继承自I/O类库的基类InputStream和OutputStream,这是decorator模式的关键(惟有这样decorator类的接口才能与它要服务的对象的完全相同)。
用FilterInputStream读取InputStream
FilterInputStream及其派生类有两项重要任务。
DataInputStream可以读取各种primitive及String。
(所有的方法都以"read"打头,比如readByte(),readFloat())。
它,以及它的搭档DataOutputStream,能让你通过流将primitive数据从一个地方导到另一个地方。
这些"地方"都列在表12-1里。
其它的类都是用来修改InputStream的内部行为的:
是不是做缓冲,是不是知道它所读取的行信息(允许你读取行号或设定行号),是不是会弹出单个字符。
后两个看上去更像是给编译器用的(也就是说,它们大概是为Java编译器设计的),所以通常情况下,你是不大会用到它们的。
不论你用哪种I/O设备,输入的时候,最好都做缓冲。
所以对I/O类库来说,比较明智的做法还是把不缓冲当特例(或者去直接调用方法),而不是像现在这样把缓冲当作特例。
JAVA
TheJavaI/OSystem
Creatingagoodinput/output(I/O)systemisoneofthemoredifficulttasksforthelanguagedesigner.
Thisisevidencedbythenumberofdifferentapproaches.Thechallengeseemstobeincoveringalleventualities.NotonlyaretheredifferentsourcesandsinksofI/Othatyouwanttocommunicatewith(files,theconsole,networkconnections,etc.),butyouneedtotalktotheminawidevarietyofways(sequential,random-access,buffered,binary,character,bylines,bywords,etc.).
TheJavalibrarydesignersattackedthisproblembycreatinglotsofclasses.Infact,therearesomanyclassesforJava’sI/Osystemthatitcanbeintimidatingatfirst(ironically,theJavaI/Odes