java io重定向

翻译:Cherami
email:cherami@163.net 
原文:http://developer.java.sun.com/developer/TechTips/2000/tt0815.html


如果你经常使用UNIX 或者 Windows shells (命令处理器),你可能经常像这样使用I/O重定向:
    $ command >outfile
这个用法是说:运行一个命令,并将它的标准输出 (例如System.out.println的输出)定向到指定的文件而不是输出到控制台或者屏幕。
这个特性非常有用。在java程序中也可以达到这个目的而不用依赖与shell。通常情况下如果你使用的编程风格依赖于标准输入输出 (就像UNIX shell 和其它工具包那样), 你可能不需要或者不想在程序里面重定向。但是有时候你希望这样,让我们看几个范例。 
第一个范例重定向标准输出到一个文件:
    import java.io.*;
    public class RedirectDemo1 {
        public static void main(String args[]) throws IOException {
            // 在文件上建立一个PrintStream 
            FileOutputStream fos =
                new FileOutputStream("out.txt");
            BufferedOutputStream bos =
                new BufferedOutputStream(fos, 1024);
            PrintStream ps =
                new PrintStream(bos, false);
            // 重定向System.out 到该文件
            System.setOut(ps);
            // 输出
            System.out.println("This is a test/u4321");
            int n = 37;
            System.out.println("The square of " + n +
                " is " + (n * n));
            ps.close();
        }
    }

标准输出 (System.out) 是PrintStream 对象的一个引用。为了重定向输出,创建一个这样的对象来表示一个文件或者其它的输出流 (例如一个网络连接)。然后使用System.setOut 调用改变System.out 引用。
JDK 1.3 中实现的java.lang.System 代码是这样的形式: 
    FileOutputStream fdOut =
        new FileOutputStream(FileDescriptor.out);
    setOut0(new PrintStream(
        new BufferedOutputStream(fdOut, 128), true));
这个代码初始化System.out。因此,在缺省情况下,System.out 是一个PrintStream,该 PrintStream 是从FileDescriptor.out 创建的一个FileOutputStream 文件,带有128字节的缓冲区,自动刷新(遇到新行符或者字节向量时自动输出)。当输出像上面那样被重定向,System.out 变成使用System.setOut传递进来的一个新创建的PrintStream 对象的引用。
RedirectDemo1 有几个问题,首先是PrintStream 使用平台缺省的字符编码将字符转换为字节。这通常是好事,例如,如果你的小程序中有这样一行:
    System.out.println("this is a test");
而且你在美国这样运行程序:
    $ java prog >outfile
程序在文件"outfile"中存入ASCII字符。这可能是你想要的得到的7位的ASCII文本文件。
但是程序中如果有Unicode字符'/u4321',它将被转换为一个'?' 。如果你查看文件你可以看到?。换句话说,缺省的编码没有正确的处理那个输出字符。
另一个问题是I/O 重定向可以被推广,例如你能将输出定向到一个字符串而不是一个文件。这里有一个范例包括了上面的两个问题:
    import java.io.*;
    public class RedirectDemo2 {
        public static void main(String args[]) throws IOException {
            // 在StringWriter 上建立一个PrintWriter。
            StringWriter sw = new StringWriter();
            PrintWriter pw = new PrintWriter(sw);
            // 输出一些东西到StringWriter
            pw.println("This is a test/u4321");
            int n = 37;
            pw.println("The square of " + n + " is " + (n * n));
            // 得到被写入的字符串
            String str = sw.toString();
            // 显式它
            System.out.print(str);
            // 将字符串输出到文件,使用 UTF-8 编码
            FileOutputStream fos =
                new FileOutputStream("out.txt");
            OutputStreamWriter osw =
                new OutputStreamWriter(fos, "UTF-8");
            BufferedWriter bw =
                new BufferedWriter(osw);
            bw.write(str);
            bw.close();
            // 读回字符串并检查
            FileInputStream fis =
                new FileInputStream("out.txt");
            InputStreamReader isr =
                new InputStreamReader(fis, "UTF-8");
            BufferedReader br =
                new BufferedReader(isr);
            String s1 = br.readLine();
            String s2 = br.readLine();
            br.close();
            String linesep = System.getProperty("line.separator");
            if (!str.equals(s1 + linesep + s2 + linesep))
                System.err.println("equals check failed");
        }
    }

范例的第一部分在一个StringWriter 上建立一个PrintWriter对象,它和PrintStream 类似,但是操作的是字符而不是字节流。StringWriter 用于向一个动态的内部缓冲区聚集字符,以后恢复为一个String或者StringBuffer。
在输出被写入StringWriter 后,聚集的字符串恢复了,然后字符串使用OutputStreamWriter和 UTF-8编码被写入文件。这个编码在所有的java实现中都被支持。它将'/u0001' 到 '/u007f'范围内的字符编码为一个字节而其它字符为两个或者三个字节。
最后,字符串从文件读回,还是使用UTF-8 编码。然后和原始的字符串比较。原始的字符串内有两个行分隔符,因此读回的是两个字符串,为了比较而添加了行分隔符。
注意你也可以从一个文件或者字符串重定向输入,使用一个像StringReader这样的类。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值