以下文档格式全部为word格式,下载后您可以任意修改编辑。
毕业设计(论文)外文文献翻译译文:Java IO 系统[1]对编程语言的设计者来说,创建一套好的输入输出(IO)系统,是一项难度极高的任务。
这一类可以从解决方案的数量之多上看出端倪。
这个问题就难在它要面对的可能性太多了。
不仅是因为有那么多的IO的源和目的(文件,控制台,网络连接等等),而且还有很多方法(顺序的,随机的,缓存的,二进制的,字符方式的,行的,字的等等)。
Java类库的设计者们用“创建很多类”的办法来解决这个问题。
坦率地说,Java IO系统的类实在太多了,以至于初看起来会把人吓着(但是,具有讽刺意味的是,这种设计实际上是限制了类的爆炸性增长)。
此外,Java在1.0版之后又对其IO类库进行了重大的修改,原先是面向byte的,现在又补充了面向Unicode字符的类库。
为了提高性能,完善功能,JDK1.4又加了一个nio(意思是“new IO”。
这个名字会用上很多年)。
这么以来,如果你想对Java 的IO类库有个全面了解,并且做到运用自如,你就得先学习大量的类。
此外,了解IO类库的演化历史也是相当重要的。
可能你的第一反应是“别拿什么历史来烦我了,告诉我怎么用就可以了!”但问题是,如果你对这段一无所知,很快就会被一些有用或是没用的类给搞糊涂了。
本文会介绍Java 标准类库中的各种IO类,及其使用方法。
File 类在介绍直接从流里读写数据的类之前,我们先介绍一下处理文件和目录的类。
你会认为这是一个关于文件的类,但它不是。
你可以用它来表示某个文件的名字,也可以用它来表示目录里一组文件的名字。
如果它表示的是一组文件,那么你还可以用list( )方法来进行查询,让它会返回String 数组。
由于元素数量是固定的,因此数组会比容器更好一些。
如果你想要获取另一个目录的清单,再建一个File对象就是了。
目录列表器假设你想看看这个目录。
有两个办法。
一是不带参数调用list( )。
它返回的是File对象所含内容的完整清单。
但是,如果你要的是一个"限制性列表(restricted list)"的话——比方说,你想看看所有扩展名为.java的文件——那么你就得使用"目录过滤器"了。
这是一个专门负责挑选显示File对象的内容的类。
FilenameFilter接口的声明:public interface FilenameFilter {boolean accept(File dir, String name);}accept( )方法需要两个参数,一个是File对象,表示这个文件是在哪个目录里面的;另一个是String,表示文件名。
虽然你可以忽略它们中的一个,甚至两个都不管,但是你大概总得用一下文件名吧。
记住,list( )会对目录里的每个文件调用accept( ),并以此判断是不是把它包括到返回值里;这个判断依据就是accept( )的返回值。
切记,文件名里不能有路径信息。
为此你只要用一个String对象来创建File对象,然后再调用这个File对象的getName( )就可以了。
它会帮你剥离路径信息(以一种平台无关的方式)。
然后再在accept( )里面用正则表达式(regular expression)的matcher对象判断,regex是否与文件名相匹配。
兜完这个圈子,list( )方法返回了一个数组。
匿名内部类这是用匿名内部类来征程程序的绝佳机会。
下面我们先创建一个返回FilenameFileter的filter()方法。
Uses anonymous inner classes.import java.io.*;import java.util.*;import com.bruceeckel.util.*;public class DirList2 {public static FilenameFilterfilter(final String afn) {Creation of anonymous inner class:return new FilenameFilter() {String fn = afn;public boolean accept(File dir, String n) {Strip path information:String f = new File(n).getName();return f.indexOf(fn) != -1;}}; End of anonymous inner class}public static void main(String[] args) {File path = new File(".");String[] list;if(args.length == 0)list = path.list();elselist = path.list(filter(args[0]));Arrays.sort(list,new AlphabeticComparator());for(int i = 0; i < list.length; i++)System.out.println(list[i]);}}注意,filter( )的参数必须是final的。
要想在匿名内部类里使用其作用域之外的对象,只能这么做。
这是对前面所讲的代码的改进,现在FilenameFilter类已经与DirList2紧紧地绑在一起了。
不过你还可以更进一步,把这个匿名内部类定义成list()的参数,这样代码会变得更紧凑:Building the anonymous inner class "in-place."import java.io.*;import java.util.*;import com.bruceeckel.util.*;public class DirList3 {public static void main(final String[] args) {File path = new File(".");String[] list;if(args.length == 0)list = path.list();elselist = path.list(new FilenameFilter() {public booleanaccept(File dir, String n) {String f = new File(n).getName();return f.indexOf(args[0]) != -1;}});Arrays.sort(list,new AlphabeticComparator());for(int i = 0; i < list.length; i++)System.out.println(list[i]);}}现在该轮到main()的参数成final了,因为匿名内部类要用它的arg[0].这个例子告诉我们,可以用匿名内部类来创建专门供特定问题用的,一次性的类。
这种做法的好处是,它能把解决某个问题的代码全部集中到一个地方。
但是从另一角度来说,这样做会使代码的可读性变差,所以要慎重。
查看与创建目录File类的功能不仅限于显示文件或目录。
它还能帮你创建新的目录甚至是目录路径(directorypath),如果目录不存在的话。
此外它还能用来检查文件的属性(大小,上次修改的日期,读写权限等),判断File对象表示的是文件还是目录,以及删除文件。
renameTo( )这个方法会把文件重命名成(或者说移动到)新的目录,也就是参数所给出的目录。
而参数本身就是一个File对象。
这个方法也适用于目录。
输入与输出IO类库常使用"流(stream)"这种抽象。
所谓"流"是一种能生成或接受数据的,代表数据的源和目标的对象。
流把IO设备内部的具体操作给隐藏起来了。
正如JDK文档所示的,Java的IO类库分成输入和输出两大部分。
所有InputStream和Reader的派生类都有一个基本的,继承下来的,能读取单个或byte数组的read( )方法。
同理,所有OutputStream和Writer 的派生类都有一个基本的,能写入单个或byte数组的write( )方法。
但通常情况下,你是不会去用这些方法的;它们是给其它类用的——而后者会提供一些更实用的接口。
因此,你很少会碰到只用一个类就能创建一个流的情形,实际上你得把多个对象叠起来,并以此来获取所需的功能。
Java的流类库之所以会那么让人犯晕,最主要的原因就是"你必须为创建一个流而动用多个对象"。
我们最好还是根据其功能为这些class归个类。
Java 1.0 的类库设计者们是从决定“让所有与输入相关的类去继承InputStream”入手的。
同理,所有与输出相关的类就该继承OutputStream了。
添加属性与适用的接口使用"分层对象(layered objects)",为单个对象动态地,透明地添加功能的做法,被称为DecoratorPattern。
(模式是Thinkingin Patterns (with Java)的主题。
)Decorator模式要求所有包覆在原始对象之外的对象,都必须具有与之完全相同的接口。
这使得decorator的用法变得非常的透明--无论对象是否被decorate过,传给它的消息总是相同的。
这也是Java IO类库要有"filter(过滤器)"类的原因:抽象的"filter"类是所有decorator的基类。
(decorator必须具有与它要包装的对象的全部接口,但是decorator可以扩展这个接口,由此就衍生出了很多"filter"类)。
Decorator模式常用于如下的情形:如果用继承来解决各种需求的话,类的数量会多到不切实际的地步。
Java的IO类库需要提供很多功能的组合,于是decorator模式就有了用武之地。
但是decorator有个缺点,在提高编程的灵活性的同时(因为你能很容易地混合和匹配属性),也使代码变得更复杂了。
Java的IO类库之所以会这么怪,就是因为它"必须为一个IO对象创建很多类",也就是为一个"核心"IO类加上很多decorator。
为InputStream和OutputStream定义decorator类接口的类,分别是FilterInputStream和FilterOutputStream。