友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!阅读过程发现任何错误请告诉我们,谢谢!! 报告错误
一世书城 返回本书目录 我的书架 我的书签 TXT全本下载 进入书吧 加入书签

Java编程思想第4版[中文版](PDF格式)-第102章

按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!




同的接口)。除此以外,还可看到程序中使用了seek(),以便在文件中到处移动,对某个值作出修改。  



10。5。3 快捷文件处理  



由于以前采用的一些典型形式都涉及到文件处理,所以大家也许会怀疑为什么要进行那么多的代码输入—— 

这正是装饰器方案一个缺点。本部分将向大家展示如何创建和使用典型文件读取和写入配置的快捷版本。这 

些快捷版本均置入package。bruceeckel。tools 中(自第5 章开始创建)。为了将每个类都添加到库内, 

只需将其置入适当的目录,并添加对应的package 语句即可。  

  

7。 快速文件输入  

若想创建一个对象,用它从一个缓冲的DataInputStream 中读取一个文件,可将这个过程封装到一个名为 

InFile 的类内。如下所示:  

  

//: InFile。java  

// Shorthand class for opening an input file  

package 。bruceeckel。tools;  

import java。io。*;  

  

public class InFile extends DataInputStream {  

  public InFile(String filename)  

    throws FileNotFoundException {  

    super(  

      new BufferedInputStream(  

        new FileInputStream(filename)));  

  }  

  public InFile(File file)  



                                                                                 298 


…………………………………………………………Page 300……………………………………………………………

    throws FileNotFoundException {  

    this(file。getPath());  

  }  

} ///:~  

  

无论构建器的String 版本还是File 版本都包括在内,用于共同创建一个 FileInputStream。  

就象这个例子展示的那样,现在可以有效减少创建文件时由于重复强调造成的问题。  

  

8。 快速输出格式化文件  

亦可用同类型的方法创建一个PrintStream,令其写入一个缓冲文件。下面是对。bruceeckel。tools 的扩 

展:  

  

//: PrintFile。java  

// Shorthand class for opening an output file  

// for human…readable output。  

package 。bruceeckel。tools;  

import java。io。*;  

  

public class PrintFile extends PrintStream {  

  public PrintFile(String filename)  

    throws IOException {  

    super(  

      new BufferedOutputStream(  

        new FileOutputStream(filename)));  

  }  

  public PrintFile(File file)  

    throws IOException {  

    this(file。getPath());  

  }  

} ///:~  

  

注意构建器不可能捕获一个由基础类构建器“掷”出的违例。  

  

9。 快速输出数据文件  

最后,利用类似的快捷方式可创建一个缓冲输出文件,用它保存数据(与由人观看的数据格式相反):  

  

//: OutFile。java  

// Shorthand class for opening an output file  

// for data storage。  

package 。bruceeckel。tools;  

import java。io。*;  

  

public class OutFile extends DataOutputStream {  

  public OutFile(String filename)  

    throws IOException {  

    super(  

      new BufferedOutputStream(  

        new FileOutputStream(filename)));  

  }  

  public OutFile(File file)  

    throws IOException {  

    this(file。getPath());  



                                                                                          299 


…………………………………………………………Page 301……………………………………………………………

  }  

} ///:~  

  

非常奇怪的是(也非常不幸),Java 库的设计者居然没想到将这些便利措施直接作为他们的一部分标准提 

供。  



10。5。4 从标准输入中读取数据  



以Unix 首先倡导的“标准输入”、“标准输出”以及“标准错误输出”概念为基础,Java 提供了相应的 

System。in,System。out 以及System。err。贯这一整本书,大家都会接触到如何用 System。out进行标准输 

出,它已预封装成一个 PrintStream 对象。System。err 同样是一个PrintStream,但System。in 是一个原始 

的InputStream,未进行任何封装处理。这意味着尽管能直接使用 System。out 和System。err,但必须事先封 

装System。in,否则不能从中读取数据。  

典型情况下,我们希望用readLine()每次读取一行输入信息,所以需要将System。in 封装到一个 

DataInputStream 中。这是Java 1。0 进行行输入时采取的“老”办法。在本章稍后,大家还会看到 Java 1。1 

的解决方案。下面是个简单的例子,作用是回应我们键入的每一行内容:  

  

//: Echo。java  

// How to read from standard input  

import java。io。*;  

  

public class Echo {  

  public static void main(String'' args) {  

    DataInputStream in =  

      new DataInputStream(  

        new BufferedInputStream(System。in));  

    String s;  

    try {  

      while((s = in。readLine())。length() != 0)  

        System。out。println(s);  

      // An empty line terminates the program  

    } catch(IOException e) {  

      e。printStackTrace();  

    }  

  }  

} ///:~  

  

之所以要使用try 块,是由于 readLine()可能“掷”出一个 IOException。注意同其他大多数流一样,也应 

对System。in 进行缓冲。  

由于在每个程序中都要将System。in 封装到一个 DataInputStream 内,所以显得有点不方便。但采用这种设 

计方案,可以获得最大的灵活性。  



10。5。5 管道数据流  



本章已简要介绍了 PipedInputStream (管道输入流)和PipedOutputStream (管道输出流)。尽管描述不十 

分详细,但并不是说它们作用不大。然而,只有在掌握了多线程处理的概念后,才可真正体会它们的价值所 

在。原因很简单,因为管道化的数据流就是用于线程之间的通信。这方面的问题将在第 14 章用一个示例说 

明。  



10。6 StreamTokenizer  



尽管StreamTokenizer 并不是从 InputStream或 OutputStream 衍生的,但它只随同 InputStream工作,所以 

十分恰当地包括在库的 IO部分中。  

StreamTokenizer 类用于将任何 InputStream分割为一系列“记号”(Token)。这些记号实际是一些断续的 



                                                                                       300 


…………………………………………………………Page 302……………………………………………………………

文本块,中间用我们选择的任何东西分隔。例如,我们的记号可以是单词,中间用空白(空格)以及标点符 

号分隔。  

下面是一个简单的程序,用于计算各个单词在文本文件中重复出现的次数:  

  

//: SortedWordCount。java  

// Counts words in a file; outputs  

// results in sorted form。  

import java。io。*;  

import java。util。*;  

import c08。*; // Contains StrSortVector  

  

class Counter {  

  private int i = 1;  

  int read() { return i; }  

  void increment() { i++; }  

}  

  

public class SortedWordCount {  

  private FileInputStream file;  

  private StreamTokenizer st;  

  private Hashtable counts = new Hashtable();  

  SortedWordCount(String filename)  

    throws FileNotFoundException {  

    try {  

      file = new FileInputStream(filename);  

      st = new StreamTokenizer(file);  

      st。ordinaryChar('。');  

      st。ordinaryChar('…');  

    } catch(FileNotFoundException e) {  

      System。out。println(  

        〃Could not open 〃 + filename);  

      throw e;  

    }  

  }  

  void cleanup() {  

    try {  

      file。close();  

    } catch(IOException e) {  

      System。out。println(  

        〃file。close() unsuccessful〃);  

    }  

  }  

  void countWords() {  

    try {  

      while(st。nextToken() !=  

        StreamTokenizer。TT_EOF) {  

        String s;  

        switch(st。ttype) {  

          case StreamTokenizer。TT_EOL:  

            s = new String(〃EOL〃);  

            break;  

          case StreamTokenizer。TT_NUMBER:  



                                                                                             301 


…………………………………………………………Page 303……………………………………………………………

            s = Double。toString(st。nval);  

            break;  

          case StreamTokenizer。TT_WORD:  

            s = st。sval; // Already a String  

            break;  

          default: // single character in ttype  

            s = String。valueOf((char)st。ttype);  

        }  

        if(counts。containsKey(s))  

          ((Counter)counts。get(s))。increment();  

        else  

          counts。put(s; new Counter());  

      }  

    } catch(IOException e) {  

      System。out。println(  

        〃st。nextToken() unsuccessful〃);  

    }  

  }  

  Enumeration values() {  

    return counts。elements();  

  }  

  Enumeration keys() { return counts。keys(); }  

  Counter getCounter(String s) {  

    return (Counter)counts。get(s);  

  }  

  Enumeration sortedKeys() {  

    Enumeration e = counts。keys();  

    StrSortVector sv = new StrSortVector();  

    while(e。hasMoreElements())  

      sv。addElement((String)e。nextElement());  

    // This call forces a sort:  

    return sv。e
返回目录 上一页 下一页 回到顶部 0 0
未阅读完?加入书签已便下次继续阅读!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!