第15章-输入/输出 --- 处理流的用法


第15章-输入/输出 --- 处理流的用法

 

(一)处理流的用法

     处理流可以隐藏底层设备上节点流的差异,并对外提供更加方便的输入/输出方法,让程序员只需关心高级流的操作。

    我们使用处理流的典型思路是,使用处理流来包装节点流,程序通过处理流来执行输入/输出功能,让节点流与底层的I/O设备、文件交互。

    识别处理流非常简单,只要流的构造器参数不是一个物理节点,而是已经存在的流,那么这种流就一定是处理流,而所有节点流都是直接以物理IO节点作为构造器参数的。

 

  下面程序使用PrintStream处理流来包装OutputStream,使用处理流后的输出流在输出时将更加方便:

  

复制代码
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;

public class PrintStreamTest
{
    public static void main(String[] args)
    {
        try
        {
            FileOutputStream fos = new FileOutputStream("test.txt");
            PrintStream ps = new PrintStream(fos);
            
            //使用PrintStream执行输出
            ps.println("哈哈,大家好");
            ps.println(new PrintStreamTest());
        }
        catch(IOException e)
        {
            e.printStackTrace();
        }
    }
}
复制代码

 

 

 

 

 

 (二)输出/输入流体系

    Java的输入/输出流体系提供了近40个类,这些类看上去杂乱而没有规律,但如果我们将其按功能进行分类,则不难发现其是非常规则的。的

 下表显示了Java输入/输出流体系中常用的流分类:

  

 

   从上表可以看出,Java的输入/输出流体系之所以如此复杂,主要是因为Java为了实现更好的设计,它把IO流按功能分成了许多类,而每类中又分别提供了字节流和字符流(当然有些流无法提供字节流,有些流无法提供字符流),字节流和字符流里又分别提供了输入流和输出流两大类,所以导致整个输入/输出流体系格外复杂。

 

  下面程序示范了使用字符串作为物理节点的字符输入/输出流的用法

复制代码
import java.io.StringReader;
import java.io.StringWriter;

public class StringNodeTest
{
    public static void main(String[] args)
    {
        String src = "从明天起,做一个幸福的人\n"
                    +"喂马,劈材,周游世界\n"
                    +"从明天起,关心粮食和蔬菜\n";
        char[] buffer = new char[32];
        int hasRead = 0;
        
        try
        {
            StringReader sr = new StringReader(src);
            
            //采用循环读取的方式读取字符串
            while((hasRead = sr.read(buffer)) > 0)
            {
                System.out.println(new String(buffer,0,hasRead));
            }
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
        
        try
        {
            //创建StringWriter时,实际上以一个StringBuffer作为输出节点
            StringWriter sw = new StringWriter();
            sw.write("有一个美丽的新世界,\n");
            sw.write("她在远方等我,\n");
            System.out.println("----下面是sw字符串节点里的内容----");
            System.out.println(sw.toString());
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }
}
复制代码

 

 

 

 

 输出内容:

复制代码
从明天起,做一个幸福的人
喂马,劈材,周游世界
从明天起,关心粮
食和蔬菜

----下面是sw字符串节点里的内容----
有一个美丽的新世界,
她在远方等我,
复制代码

 

 (三)转换流

    输入/输出流体系中还提供了两个转换流,这两个转换流用于实现将字节流转换成字符流,其中InputStreamReader将字节输入流转换成字符输入流,OutputStreamWriter将字节输出流转换成字符输出流。

 

    Java没有将字符流转换为字节流的转换流,因为:字节流比字符流的使用范围更广,但字符流比字节流操作方便。如果有一个流已经是字符流了,也就是说,是一个用起来更方便的流,为什么要转换成字节流呢?反之,如果现在有一个字节流,但我们知道这个字节流的内容都是文件内容,那么把它转换成字符流来处理就会更方便一些,所以Java只提供了将字节流转换成字符流的转换流,没有提供将字符流转换成字节流的转换流。

 

   下面以获取键盘输入为例来介绍转换流的用法:

    Java使用System.in代表标准输入,即键盘输入,但这个标准输入流是InputStream类的实例,使用不太方便,而且键盘输入内容都是文本内容,所以可以使用InputStreamReader将其转换成字符输入流,普通的Reader读取输入内容时依然不太方便,我们可以将普通的Reader再次包装成BufferedReader,利用BufferedReader的readLine()方法可以一次读取一行内容。

    

复制代码
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class KeyinTest
{
    public static void main(String[] args)
    {
        try
        {
            //将System.in对象转换成Reader对象
            InputStreamReader Reader = new InputStreamReader(System.in);
            //将普通的Reader包装成BufferedReaders
            BufferedReader br = new BufferedReader(Reader);
            
            String buffer = "";
            
            //采用循环方式来逐渐地读取
            while((buffer = br.readLine()) != null)
            {
                //如果读取的字符串为"exit",则程序退出
                if(buffer.equals("exit"))
                {
                    System.exit(1);
                }
                
                //打印读取的内容
                System.out.println("输入的内容为:" + buffer);
            }
        }
        catch(IOException e)
        {
            e.printStackTrace();
        }
    }
}
posted @ 2014-04-11 07:27  JAVA之迷  阅读(100)  评论(0编辑  收藏  举报