外文翻译java_第1页
外文翻译java_第2页
外文翻译java_第3页
外文翻译java_第4页
外文翻译java_第5页
已阅读5页,还剩14页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、外文资料译文及原文 Java Java I/O 系统对编程语言的设计者来说,创建一套好的输入输出(I/O)系统,是一项难度极高的任务。这一点可以从解决方案的数量之多上看出端倪。这个问题难就难在它要面对的可能性太多了。不仅是因为有那么多I/O的源和目地(文件,控制台,网络连接等等),而且还有很多方法(顺序的sequential,随机的random-access,缓存的buffered,二进制的binary,字符方式的character,行的by lines,字的by words,等等)。 Java类库的设计者们用"创建很多类"的办法来解决这个问题。坦率地说Java I/O系统

2、的类实在是太多了,以至于初看起来会把人吓着(但是,具有讽刺意味的是,这种设计实际上是限制了类的爆炸性增长)。此外,Java在1.0版之后又对其I/O类库作了重大的修改,原先是面向byte的,现在又补充了面向Unicode字符的类库。为了提高性能,完善功能,JDK 1.4又加了一个nio(意思是"new I/O"。这个名字会用上很多年)。这么以来,如果你想对Java的I/O类库有个全面了解,并且做到运用自如,你就得先学习大量的类。此外,了解I/O类库的演化的历史也是相当重要的。可能你的第一反应是"别拿什么历史来烦我了,告诉我怎么用就可以了!"但问题是,如果

3、你对这段历史一无所知,很快就会被一些有用或是没用的类给搞糊涂了。 本章会介绍Java标准类库中的各种I/O类,及其使用方法。 File 类在介绍直接从流里读写数据的类之前,我们先介绍一下处理文件和目录的类。 File类有一个极具欺骗性的名字;或许你会认为这是一个关于文件的类,但它不是。你可以用它来表示某个文件的名字,也可以用它来表示目录里一组文件的名字。如果它表示的是一组文件,那么你还可以用list( )方法来进行查询,让它会返回String数组。由于元素数量是固定的,因此数组会比容器更好一些。如果你想要获取另一个目录的清单,再建一个File对象就是了。实际上,叫它 "FilePat

4、h"可能会更好一些。下面我们举例说明怎样使用这个类及其相关的FilenameFilter接口。 目录列表器假设你想看看这个目录。有两个办法。一是不带参数调用list( )。它返回的是File对象所含内容的完整清单。但是,如果你要的是一个"限制性列表(restricted list)"的话 比方说,你想看看所有扩展名为.java的文件 那么你就得使用"目录过滤器"了。这是一个专门负责挑选显示File对象的内容的类。 下面就是源代码。看看,用了java.utils.Arrays.sort( )和11章的AlphabeticComparator之后,

5、我们没费吹灰之力就对结果作了排序(按字母顺序): /: c12:DirList.java/ Displays directory listing using regular expressions./ Args: "D.*.java"import java.io.*;import java.util.*;import java.util.regex.*;import com.bruceeckel.util.*;public class DirList public static void main(String args) File path = new File(&quo

6、t;."); String list; if(args.length = 0) list = path.list(); else list = path.list(new DirFilter(args0); Arrays.sort(list, new AlphabeticComparator(); for(int i = 0; i < list.length; i+) System.out.println(listi); class DirFilter implements FilenameFilter private Pattern pattern; public DirFi

7、lter(String regex) pattern = Ppile(regex); public boolean accept(File dir, String name) / Strip path information, search for regex: return pattern.matcher( new File(name).getName().matches(); /:DirFilter实现了FilenameFilter接口。我们来看看FilenameFilter究竟有多简单: public interface FilenameFilter boolean accept(Fil

8、e dir, String name);也就是说,这类对象的任务就是提供一个accept( )的方法。之所以要创建这个类,就是要给list( )提供一个accept( )方法,这样当list( )判断该返回哪些文件名的时候,能够"回过头来调用"accept( )方法。因此,这种结构通常被称为回调(callback)。更准确地说,由于list( )实现了基本功能,而FilenameFilter提供了"对外服务所需的算法",因此这是一种"策略模式(Strategy Pattern)"。由于list( )拿FilenameFilter对象当

9、参数,因此你可以将任何实现FilenameFilter接口的对象传给它,并以此(甚至是在运行时)控制list( )的工作方式。回调能提高程序的灵活性。 DirFilter还告诉我们,interface只是包含了一些方法,它没说你只能写这些方法。(但是,你至少要定义接口里有的方法。) 这里我们还定义了DirFilter的构造函数。 accept( )方法需要两个参数,一个是File对象,表示这个文件是在哪个目录里面的;另一个是String,表示文件名。虽然你可以忽略它们中的一个,甚至两个都不管,但是你大概总得用一下文件名吧。记住,list( )会对目录里的每个文件调用accept( ),并以此判

10、断是不是把它包括到返回值里;这个判断依据就是accept( )的返回值。 切记,文件名里不能有路径信息。为此你只要用一个String对象来创建File对象,然后再调用这个File对象的getName( )就可以了。它会帮你剥离路径信息(以一种平台无关的方式)。然后再在accept( )里面用正则表达式(regular expression)的matcher对象判断,regex是否与文件名相匹配。兜完这个圈子,list( )方法返回了一个数组。 匿名内部类这是用匿名内部类(详见第八章)来重写程序的绝佳机会。下面我们先创建一个返回FilenameFilter的filter( )方法。 /: c12

11、:DirList2.java/ Uses anonymous inner classes./ Args: "D.*.java"import java.io.*;import java.util.*;import java.util.regex.*;import com.bruceeckel.util.*;public class DirList2 public static FilenameFilter filter(final String regex) / Creation of anonymous inner class: return new FilenameFil

12、ter() private Pattern pattern = Ppile(regex); public boolean accept(File dir, String name) return pattern.matcher( new File(name).getName().matches(); ; / End of anonymous inner class public static void main(String args) File path = new File("."); String list; if(args.length = 0) list = pa

13、th.list(); else list = path.list(filter(args0); Arrays.sort(list, new AlphabeticComparator(); for(int i = 0; i < list.length; i+) System.out.println(listi); /:注意,filter( )的参数必须是final的。要想在匿名内部类里使用其作用域之外的对象,只能这么做。 这是对前面所讲的代码的改进,现在FilenameFilter类已经与DirList2紧紧地绑在一起了。不过你还可以更进一步,把这个匿名内部类定义成list( )的参数,这

14、样代码会变得更紧凑: /: c12:DirList3.java/ Building the anonymous inner class "in-place."/ Args: "D.*.java"import java.io.*;import java.util.*;import java.util.regex.*;import com.bruceeckel.util.*;public class DirList3 public static void main(final String args) File path = new File(".

15、"); String list; if(args.length = 0) list = path.list(); else list = path.list(new FilenameFilter() private Pattern pattern = Ppile(args0); public boolean accept(File dir, String name) return pattern.matcher( new File(name).getName().matches(); ); Arrays.sort(list, new AlphabeticComparator(); f

16、or(int i = 0; i < list.length; i+) System.out.println(listi); /:现在该轮到main( )的参数成final了,因为匿名内部类要用它的arg0了。 这个例子告诉我们,可以用匿名内部类来创建专门供特定问题用的,一次性的类。这种做法的好处是,它能把解决某个问题的代码全都集中到一个地方。但是从另一角度来说,这样做会使代码的可读性变差,所以要慎重。 查看与创建目录File类的功能不仅限于显示文件或目录。它还能帮你创建新的目录甚至是目录路径(directory path),如果目录不存在的话。此外它还能用来检查文件的属性(大小,上次修改

17、的日期,读写权限等),判断File对象表示的是文件还是目录,以及删除文件。下面这段程序演示了File类的一些其他方法(请查阅JDK文档,以了解其全部功能): /: c12:MakeDirectories.java/ Demonstrates the use of the File class to/ create directories and manipulate files./ Args: MakeDirectoriesTestimport com.bruceeckel.simpletest.*;import java.io.*;public class MakeDirectories p

18、rivate static Test monitor = new Test(); private static void usage() System.err.println( "Usage:MakeDirectories path1 .n" + "Creates each pathn" + "Usage:MakeDirectories -d path1 .n" + "Deletes each pathn" + "Usage:MakeDirectories -r path1 path2n" +

19、"Renames from path1 to path2"); 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 g

20、etParent: " + f.getParent() + "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"

21、); public static void main(String args) if(args.length < 1) usage(); if(args0.equals("-r") if(args.length != 3) usage(); File old = new File(args1), rname = new File(args2); old.renameTo(rname); fileData(old); fileData(rname); return; / Exit main int count = 0; boolean del = false; if(a

22、rgs0.equals("-d") count+; del = true; count-; while(+count < args.length) File f = new File(argscount); 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.

23、println("created " + f); fileData(f); if(args.length = 1 && args0.equals("MakeDirectoriesTest") monitor.expect(new String "% (MakeDirectoriesTest exists"+ "|created MakeDirectoriesTest)", "% Absolute path: " + "S+MakeDirectoriesTest"

24、;, "% Can read: (true|false)", "% Can write: (true|false)", " getName: MakeDirectoriesTest", " getParent: null", " getPath: MakeDirectoriesTest", "% length: d+", "% lastModified: d+", "It's a directory" ); /:在fileDat

25、a( )演示了全套查询文件和目录路径信息的方法。 main( )的第一条指令就是执行renameTo( )。它会把文件重命名成(或者说移动到)新的目录,也就是参数所给出的目录。而参数本身就是一个File对象。这个方法也适用于目录。 如果你试过上面那段程序,就会发现,你能用它创建任意复杂的目录路径,因为mkdirs( )已经帮你打理好了。 输入与输出I/O类库常使用"流(stream)"这种抽象。所谓"流"是一种能生成或接受数据的,代表数据的源和目标的对象。流把I/O设备内部的具体操作给隐藏起来了。 正如JDK文档所显示的,Java的I/O类库分成输入和输

26、出两大部分。所有InputStream和Reader的派生类都有一个基本的,继承下来的,能读取单个或byte数组的read( )方法。同理,所有OutputStream和Writer的派生类都有一个基本的,能写入单个或byte数组的write( )方法。但通常情况下,你是不会去用这些方法的;它们是给其它类用的 而后者会提供一些更实用的接口。因此,你很少会碰到只用一个类就能创建一个流的情形,实际上你得把多个对象叠起来,并以此来获取所需的功能。Java的流类库之所以会那么让人犯晕,最主要的原因就是"你必须为创建一个流而动用多个对象"。 我们最好还是根据其功能为这些class归个

27、类。Java 1.0的类库设计者们是从决定"让所有与输入相关的类去继承InputStream"入手的。同理,所有与输出相关的类就该继承OutputStream了。添加属性与适用的接口使用"分层对象(layered objects)",为单个对象动态地,透明地添加功能的做法,被称为Decorator Pattern。(模式61是Thinking in Patterns (with Java)的主题。)Decorator模式要求所有包覆在原始对象之外的对象,都必须具有与之完全相同的接口。这使得decorator的用法变得非常的透明-无论对象是否被decora

28、te过,传给它的消息总是相同的。这也是Java I/O类库要有"filter(过滤器)"类的原因:抽象的"filter"类是所有decorator的基类。(decorator必须具有与它要包装的对象的全部接口,但是decorator可以扩展这个接口,由此就衍生出了很多"filter"类)。 Decorator模式常用于如下的情形:如果用继承来解决各种需求的话,类的数量会多到不切实际的地步。Java的I/O类库需要提供很多功能的组合,于是decorator模式就有了用武之地。62 但是decorator有个缺点,在提高编程的灵活性的同时

29、(因为你能很容易地混合和匹配属性),也使代码变得更复杂了。Java的I/O类库之所以会这么怪,就是因为它"必须为一个I/O对象创建很多类",也就是为一个"核心"I/O类加上很多decorator。 为InputStream和OutputStream定义decorator类接口的类,分别是FilterInputStream和FilterOutputStream。这两个名字都起得不怎么样。FilterInputStream和FilterOutputStream都继承自I/O类库的基类InputStream和OutputStream,这是decorator模式

30、的关键(惟有这样decorator类的接口才能与它要服务的对象的完全相同)。 用FilterInputStream读取InputStreamFilterInputStream及其派生类有两项重要任务。DataInputStream可以读取各种primitive及String。(所有的方法都以"read"打头,比如readByte( ), readFloat( )。它,以及它的搭档DataOutputStream,能让你通过流将primitive数据从一个地方导到另一个地方。这些"地方"都列在表12-1里。 其它的类都是用来修改InputStream的内部

31、行为的:是不是做缓冲,是不是知道它所读取的行信息(允许你读取行号或设定行号),是不是会弹出单个字符。后两个看上去更像是给编译器用的(也就是说,它们大概是为Java编译器设计的),所以通常情况下,你是不大会用到它们的。 不论你用哪种I/O设备,输入的时候,最好都做缓冲。所以对I/O类库来说,比较明智的做法还是把不缓冲当特例(或者去直接调用方法),而不是像现在这样把缓冲当作特例。 JAVAThe Java I/O SystemCreating a good input/output (I/O) system is one of the more difficult tasks for the la

32、nguage designer.This is evidenced by the number of different approaches. The challenge seems to be in covering all eventualities. Not only are there different sources and sinks of I/O that you want to communicate with (files, the console, network connections, etc.), but you need to talk to them in a

33、 wide variety of ways (sequential, random-access, buffered, binary, character, by lines, by words, etc.). The Java library designers attacked this problem by creating lots of classes. In fact, there are so many classes for Javas I/O system that it can be intimidating at first (ironically, the Java I

34、/O design actually prevents an explosion of classes). There was also a significant change in the I/O library after Java 1.0, when the original byte-oriented library was supplemented with char-oriented, Unicode-based I/O classes. In JDK 1.4, the nio classes (for “new I/O,” a name well still be using

35、years from now) were added for improved performance and functionality. As a result, there are a fair number of classes to learn before you understand enough of Javas I/O picture that you can use it properly. In addition, its rather important to understand the evolution history of the I/O library, ev

36、en if your first reaction is “dont bother me with history, just show me how to use it!” The problem is that without the historical perspective, you will rapidly become confused with some of the classes and when you should and shouldnt use them. This chapter will give you an introduction to the varie

37、ty of I/O classes in the standard Java library and how to use them. The File classBefore getting into the classes that actually read and write data to streams, well look at a utility provided with the library to assist you in handling file directory issues. The File class has a deceiving name; you m

38、ight think it refers to a file, but it doesnt. It can represent either the name of a particular file or the names of a set of files in a directory. If its a set of files, you can ask for that set using the list( ) method, which returns an array of String. It makes sense to return an array rathe

39、r than one of the flexible container classes, because the number of elements is fixed, and if you want a different directory listing, you just create a different File object. In fact, “FilePath” would have been a better name for the class. This section shows an example of the use of this class, incl

40、uding the associated FilenameFilter interface. A directory listerSuppose youd like to see a directory listing. The File object can be listed in two ways. If you call list( ) with no arguments, youll get the full list that the File object contains. However, if you want a restricted listfor examp

41、le, if you want all of the files with an extension of .javathen you use a “directory filter,” which is a class that tells how to select the File objects for display. Heres the code for the example. Note that the result has been effortlessly sorted (alphabetically) using the java.utils.Arrays.sort(&#

42、160;) method and the AlphabeticComparator defined in Chapter 11:/: c12:DirList.java/ Displays directory listing using regular expressions./ Args: "D.*.java"import java.io.*;import java.util.*;import java.util.regex.*;import com.bruceeckel.util.*;public class DirList public static void main

43、(String args) File path = new File("."); String list; if(args.length = 0) list = path.list(); else list = path.list(new DirFilter(args0); Arrays.sort(list, new AlphabeticComparator(); for(int i = 0; i < list.length; i+) System.out.println(listi); class DirFilter implements FilenameFilte

44、r private Pattern pattern; public DirFilter(String regex) pattern = Ppile(regex); public boolean accept(File dir, String name) / Strip path information, search for regex: return pattern.matcher( new File(name).getName().matches(); /:The DirFilter class “implements” the interface FilenameFilter. Its

45、useful to see how simple the FilenameFilter interface is: public interface FilenameFilter boolean accept(File dir, String name);It says all that this type of object does is provide a method called accept( ). The whole reason behind the creation of this class is to provide the accept( ) met

46、hod to the list( ) method so that list( ) can “call back” accept( ) to determine which file names should be included in the list. Thus, this structure is often referred to as a callback. More specifically, this is an example of the Strategy Pattern, because list( ) implements bas

47、ic functionality, and you provide the Strategy in the form of a FilenameFilter in order to complete the algorithm necessary for list( ) to provide its service. Because list( ) takes a FilenameFilter object as its argument, it means that you can pass an object of any class that implements F

48、ilenameFilter to choose (even at run time) how the list( ) method will behave. The purpose of a callback is to provide flexibility in the behavior of code. DirFilter shows that just because an interface contains only a set of methods, youre not restricted to writing only those methods. (You mus

49、t at least provide definitions for all the methods in an interface, however.) In this case, the DirFilter constructor is also created. The accept( ) method must accept a File object representing the directory that a particular file is found in, and a String containing the name of that file. You

50、 might choose to use or ignore either of these arguments, but you will probably at least use the file name. Remember that the list( ) method is calling accept( ) for each of the file names in the directory object to see which one should be included; this is indicated by the boolean result

51、returned by accept( ). To make sure the element youre working with is only the file name and contains no path information, all you have to do is take the String object and create a File object out of it, then call getName( ), which strips away all the path information (in a platform-indepe

52、ndent way). Then accept( ) uses a regular expression matcher object to see if the regular expression regex matches the name of the file. Using accept( ), the list( ) method returns an array. Anonymous inner classesThis example is ideal for rewriting using an anonymous inner class (des

53、cribed in Chapter 8). As a first cut, a method filter( ) is created that returns a reference to a FilenameFilter:/: c12:DirList2.java/ Uses anonymous inner classes./ Args: "D.*.java"import java.io.*;import java.util.*;import java.util.regex.*;import com.bruceeckel.util.*;public class

54、DirList2 public static FilenameFilter filter(final String regex) / Creation of anonymous inner class: return new FilenameFilter() private Pattern pattern = Ppile(regex); public boolean accept(File dir, String name) return pattern.matcher( new File(name).getName().matches(); ; / End of anonymous inne

55、r class public static void main(String args) File path = new File("."); String list; if(args.length = 0) list = path.list(); else list = path.list(filter(args0); Arrays.sort(list, new AlphabeticComparator(); for(int i = 0; i < list.length; i+) System.out.println(listi); /:Note that the

56、argument to filter( ) must be final. This is required by the anonymous inner class so that it can use an object from outside its scope. This design is an improvement because the FilenameFilter class is now tightly bound to DirList2. However, you can take this approach one step further and define the anonymous inner class as an argument to list( ), in which case its even smaller:/: c12:DirList3.ja

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论