• java io系列16之 PrintStream(打印输出流)详解


    本章介绍PrintStream以及 它与DataOutputStream的区别。我们先对PrintStream有个大致认识,然后再深入学习它的源码,最后通过示例加深对它的了解。

    转载请注明出处:http://www.cnblogs.com/skywang12345/p/io_16.html

    PrintStream 介绍

    PrintStream 是打印输出流,它继承于FilterOutputStream。
    PrintStream 是用来装饰其它输出流。它能为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式。
    与其他输出流不同,PrintStream 永远不会抛出 IOException;它产生的IOException会被自身的函数所捕获并设置错误标记, 用户可以通过 checkError() 返回错误标记,从而查看PrintStream内部是否产生了IOException。
    另外,PrintStream 提供了自动flush 和 字符集设置功能。所谓自动flush,就是往PrintStream写入的数据会立刻调用flush()函数。


    PrintStream 函数列表

    复制代码
    /* 
     * 构造函数
     */
    // 将“输出流out”作为PrintStream的输出流,不会自动flush,并且采用默认字符集
    // 所谓“自动flush”,就是每次执行print(), println(), write()函数,都会调用flush()函数;
    // 而“不自动flush”,则需要我们手动调用flush()接口。
    PrintStream(OutputStream out)
    // 将“输出流out”作为PrintStream的输出流,自动flush,并且采用默认字符集。
    PrintStream(OutputStream out, boolean autoFlush)
    // 将“输出流out”作为PrintStream的输出流,自动flush,采用charsetName字符集。
    PrintStream(OutputStream out, boolean autoFlush, String charsetName)
    // 创建file对应的FileOutputStream,然后将该FileOutputStream作为PrintStream的输出流,不自动flush,采用默认字符集。
    PrintStream(File file)
    // 创建file对应的FileOutputStream,然后将该FileOutputStream作为PrintStream的输出流,不自动flush,采用charsetName字符集。
    PrintStream(File file, String charsetName)
    // 创建fileName对应的FileOutputStream,然后将该FileOutputStream作为PrintStream的输出流,不自动flush,采用默认字符集。
    PrintStream(String fileName)
    // 创建fileName对应的FileOutputStream,然后将该FileOutputStream作为PrintStream的输出流,不自动flush,采用charsetName字符集。
    PrintStream(String fileName, String charsetName)
    
    // 将“字符c”追加到“PrintStream输出流中”
    PrintStream     append(char c)
    // 将“字符序列从start(包括)到end(不包括)的全部字符”追加到“PrintStream输出流中”
    PrintStream     append(CharSequence charSequence, int start, int end)
    // 将“字符序列的全部字符”追加到“PrintStream输出流中”
    PrintStream     append(CharSequence charSequence)
    // flush“PrintStream输出流缓冲中的数据”,并检查错误
    boolean     checkError()
    // 关闭“PrintStream输出流”
    synchronized void     close()
    // flush“PrintStream输出流缓冲中的数据”。
    // 例如,PrintStream装饰的是FileOutputStream,则调用flush时会将数据写入到文件中
    synchronized void     flush()
    // 根据“Locale值(区域属性)”来格式化数据
    PrintStream     format(Locale l, String format, Object... args)
    // 根据“默认的Locale值(区域属性)”来格式化数据
    PrintStream     format(String format, Object... args)
    // 将“float数据f对应的字符串”写入到“PrintStream输出流”中,print实际调用的是write函数
    void     print(float f)
    // 将“double数据d对应的字符串”写入到“PrintStream输出流”中,print实际调用的是write函数
    void     print(double d)
    // 将“字符串数据str”写入到“PrintStream输出流”中,print实际调用的是write函数
    synchronized void     print(String str)
    // 将“对象o对应的字符串”写入到“PrintStream输出流”中,print实际调用的是write函数
    void     print(Object o)
    // 将“字符c对应的字符串”写入到“PrintStream输出流”中,print实际调用的是write函数
    void     print(char c)
    // 将“字符数组chars对应的字符串”写入到“PrintStream输出流”中,print实际调用的是write函数
    void     print(char[] chars)
    // 将“long型数据l对应的字符串”写入到“PrintStream输出流”中,print实际调用的是write函数
    void     print(long l)
    // 将“int数据i对应的字符串”写入到“PrintStream输出流”中,print实际调用的是write函数
    void     print(int i)
    // 将“boolean数据b对应的字符串”写入到“PrintStream输出流”中,print实际调用的是write函数
    void     print(boolean b)
    // 将“数据args”根据“Locale值(区域属性)”按照format格式化,并写入到“PrintStream输出流”中
    PrintStream     printf(Locale l, String format, Object... args)
    // 将“数据args”根据“默认Locale值(区域属性)”按照format格式化,并写入到“PrintStream输出流”中
    PrintStream     printf(String format, Object... args)
    // 将“换行符”写入到“PrintStream输出流”中,println实际调用的是write函数
    void     println()
    // 将“float数据对应的字符串+换行符”写入到“PrintStream输出流”中,println实际调用的是write函数
    void     println(float f)
    // 将“int数据对应的字符串+换行符”写入到“PrintStream输出流”中,println实际调用的是write函数
    void     println(int i)
    // 将“long数据对应的字符串+换行符”写入到“PrintStream输出流”中,println实际调用的是write函数
    void     println(long l)
    // 将“对象o对应的字符串+换行符”写入到“PrintStream输出流”中,println实际调用的是write函数
    void     println(Object o)
    // 将“字符数组chars对应的字符串+换行符”写入到“PrintStream输出流”中,println实际调用的是write函数
    void     println(char[] chars)
    // 将“字符串str+换行符”写入到“PrintStream输出流”中,println实际调用的是write函数
    synchronized void     println(String str)
    // 将“字符c对应的字符串+换行符”写入到“PrintStream输出流”中,println实际调用的是write函数
    void     println(char c)
    // 将“double数据对应的字符串+换行符”写入到“PrintStream输出流”中,println实际调用的是write函数
    void     println(double d)
    // 将“boolean数据对应的字符串+换行符”写入到“PrintStream输出流”中,println实际调用的是write函数
    void     println(boolean b)
    // 将数据oneByte写入到“PrintStream输出流”中。oneByte虽然是int类型,但实际只会写入一个字节
    synchronized void     write(int oneByte)
    // 将“buffer中从offset开始的length个字节”写入到“PrintStream输出流”中。
    void     write(byte[] buffer, int offset, int length)
    复制代码

    注意print()和println()都是将其中参数转换成字符串之后,再写入到输入流。
    例如,

    print(0x61); 

    等价于

    write(String.valueOf(0x61));

    上面语句是将字符串"97"写入到输出流。0x61对应十进制数是97。

    write(0x61)

    上面语句是将字符'a'写入到输出流。因为0x61对应的ASCII码的字母'a'。

    查看下面的代码,我们能对这些函数有更清晰的认识!

    PrintStream 源码分析(基于jdk1.7.40)

    复制代码
      1 package java.io;
      2 
      3 import java.util.Formatter;
      4 import java.util.Locale;
      5 import java.nio.charset.Charset;
      6 import java.nio.charset.IllegalCharsetNameException;
      7 import java.nio.charset.UnsupportedCharsetException;
      8 
      9 public class PrintStream extends FilterOutputStream
     10     implements Appendable, Closeable
     11 {
     12 
     13     // 自动flush
     14     // 所谓“自动flush”,就是每次执行print(), println(), write()函数,都会调用flush()函数;
     15     // 而“不自动flush”,则需要我们手动调用flush()接口。
     16     private final boolean autoFlush;
     17     // PrintStream是否右产生异常。当PrintStream有异常产生时,会被本身捕获,并设置trouble为true
     18     private boolean trouble = false;
     19     // 用于格式化的对象
     20     private Formatter formatter;
     21 
     22     // BufferedWriter对象,用于实现“PrintStream支持字符集”。
     23     // 因为PrintStream是OutputStream的子类,所以它本身不支持字符串;
     24     // 但是BufferedWriter支持字符集,因此可以通过OutputStreamWriter创建PrintStream对应的BufferedWriter对象,从而支持字符集。
     25     private BufferedWriter textOut;
     26     private OutputStreamWriter charOut;
     27 
     28     private static <T> T requireNonNull(T obj, String message) {
     29         if (obj == null)
     30             throw new NullPointerException(message);
     31         return obj;
     32     }
     33 
     34     // 返回csn对应的字符集对象
     35     private static Charset toCharset(String csn)
     36         throws UnsupportedEncodingException
     37     {
     38         requireNonNull(csn, "charsetName");
     39         try {
     40             return Charset.forName(csn);
     41         } catch (IllegalCharsetNameException|UnsupportedCharsetException unused) {
     42             // UnsupportedEncodingException should be thrown
     43             throw new UnsupportedEncodingException(csn);
     44         }
     45     }
     46 
     47     // 将“输出流out”作为PrintStream的输出流,autoFlush的flush模式,并且采用默认字符集。
     48     private PrintStream(boolean autoFlush, OutputStream out) {
     49         super(out);
     50         this.autoFlush = autoFlush;
     51         this.charOut = new OutputStreamWriter(this);
     52         this.textOut = new BufferedWriter(charOut);
     53     }
     54 
     55     // 将“输出流out”作为PrintStream的输出流,自动flush,采用charsetName字符集。
     56     private PrintStream(boolean autoFlush, OutputStream out, Charset charset) {
     57         super(out);
     58         this.autoFlush = autoFlush;
     59         this.charOut = new OutputStreamWriter(this, charset);
     60         this.textOut = new BufferedWriter(charOut);
     61     }
     62 
     63     // 将“输出流out”作为PrintStream的输出流,自动flush,采用charsetName字符集。
     64     private PrintStream(boolean autoFlush, Charset charset, OutputStream out)
     65         throws UnsupportedEncodingException
     66     {
     67         this(autoFlush, out, charset);
     68     }
     69 
     70     // 将“输出流out”作为PrintStream的输出流,不会自动flush,并且采用默认字符集
     71     public PrintStream(OutputStream out) {
     72         this(out, false);
     73     }
     74 
     75     // 将“输出流out”作为PrintStream的输出流,自动flush,并且采用默认字符集。
     76     public PrintStream(OutputStream out, boolean autoFlush) {
     77         this(autoFlush, requireNonNull(out, "Null output stream"));
     78     }
     79 
     80     // 将“输出流out”作为PrintStream的输出流,自动flush,采用charsetName字符集。
     81     public PrintStream(OutputStream out, boolean autoFlush, String encoding)
     82         throws UnsupportedEncodingException
     83     {
     84         this(autoFlush,
     85              requireNonNull(out, "Null output stream"),
     86              toCharset(encoding));
     87     }
     88 
     89     // 创建fileName对应的FileOutputStream,然后将该FileOutputStream作为PrintStream的输出流,不自动flush,采用默认字符集。
     90     public PrintStream(String fileName) throws FileNotFoundException {
     91         this(false, new FileOutputStream(fileName));
     92     }
     93 
     94     // 创建fileName对应的FileOutputStream,然后将该FileOutputStream作为PrintStream的输出流,不自动flush,采用charsetName字符集。
     95     public PrintStream(String fileName, String csn)
     96         throws FileNotFoundException, UnsupportedEncodingException
     97     {
     98         // ensure charset is checked before the file is opened
     99         this(false, toCharset(csn), new FileOutputStream(fileName));
    100     }
    101 
    102     // 创建file对应的FileOutputStream,然后将该FileOutputStream作为PrintStream的输出流,不自动flush,采用默认字符集。
    103     public PrintStream(File file) throws FileNotFoundException {
    104         this(false, new FileOutputStream(file));
    105     }
    106 
    107     // 创建file对应的FileOutputStream,然后将该FileOutputStream作为PrintStream的输出流,不自动flush,采用csn字符集。
    108     public PrintStream(File file, String csn)
    109         throws FileNotFoundException, UnsupportedEncodingException
    110     {
    111         // ensure charset is checked before the file is opened
    112         this(false, toCharset(csn), new FileOutputStream(file));
    113     }
    114 
    115     private void ensureOpen() throws IOException {
    116         if (out == null)
    117             throw new IOException("Stream closed");
    118     }
    119 
    120     // flush“PrintStream输出流缓冲中的数据”。
    121     // 例如,PrintStream装饰的是FileOutputStream,则调用flush时会将数据写入到文件中
    122     public void flush() {
    123         synchronized (this) {
    124             try {
    125                 ensureOpen();
    126                 out.flush();
    127             }
    128             catch (IOException x) {
    129                 trouble = true;
    130             }
    131         }
    132     }
    133 
    134     private boolean closing = false; /* To avoid recursive closing */
    135 
    136     // 关闭PrintStream
    137     public void close() {
    138         synchronized (this) {
    139             if (! closing) {
    140                 closing = true;
    141                 try {
    142                     textOut.close();
    143                     out.close();
    144                 }
    145                 catch (IOException x) {
    146                     trouble = true;
    147                 }
    148                 textOut = null;
    149                 charOut = null;
    150                 out = null;
    151             }
    152         }
    153     }
    154 
    155     // flush“PrintStream输出流缓冲中的数据”,并检查错误
    156     public boolean checkError() {
    157         if (out != null)
    158             flush();
    159         if (out instanceof java.io.PrintStream) {
    160             PrintStream ps = (PrintStream) out;
    161             return ps.checkError();
    162         }
    163         return trouble;
    164     }
    165 
    166     protected void setError() {
    167         trouble = true;
    168     }
    169 
    170     protected void clearError() {
    171         trouble = false;
    172     }
    173 
    174     // 将数据b写入到“PrintStream输出流”中。b虽然是int类型,但实际只会写入一个字节
    175     public void write(int b) {
    176         try {
    177             synchronized (this) {
    178                 ensureOpen();
    179                 out.write(b);
    180                 if ((b == '
    ') && autoFlush)
    181                     out.flush();
    182             }
    183         }
    184         catch (InterruptedIOException x) {
    185             Thread.currentThread().interrupt();
    186         }
    187         catch (IOException x) {
    188             trouble = true;
    189         }
    190     }
    191 
    192     // 将“buf中从off开始的length个字节”写入到“PrintStream输出流”中。
    193     public void write(byte buf[], int off, int len) {
    194         try {
    195             synchronized (this) {
    196                 ensureOpen();
    197                 out.write(buf, off, len);
    198                 if (autoFlush)
    199                     out.flush();
    200             }
    201         }
    202         catch (InterruptedIOException x) {
    203             Thread.currentThread().interrupt();
    204         }
    205         catch (IOException x) {
    206             trouble = true;
    207         }
    208     }
    209 
    210     // 将“buf中的全部数据”写入到“PrintStream输出流”中。
    211     private void write(char buf[]) {
    212         try {
    213             synchronized (this) {
    214                 ensureOpen();
    215                 textOut.write(buf);
    216                 textOut.flushBuffer();
    217                 charOut.flushBuffer();
    218                 if (autoFlush) {
    219                     for (int i = 0; i < buf.length; i++)
    220                         if (buf[i] == '
    ')
    221                             out.flush();
    222                 }
    223             }
    224         }
    225         catch (InterruptedIOException x) {
    226             Thread.currentThread().interrupt();
    227         }
    228         catch (IOException x) {
    229             trouble = true;
    230         }
    231     }
    232 
    233     // 将“字符串s”写入到“PrintStream输出流”中。
    234     private void write(String s) {
    235         try {
    236             synchronized (this) {
    237                 ensureOpen();
    238                 textOut.write(s);
    239                 textOut.flushBuffer();
    240                 charOut.flushBuffer();
    241                 if (autoFlush && (s.indexOf('
    ') >= 0))
    242                     out.flush();
    243             }
    244         }
    245         catch (InterruptedIOException x) {
    246             Thread.currentThread().interrupt();
    247         }
    248         catch (IOException x) {
    249             trouble = true;
    250         }
    251     }
    252 
    253     // 将“换行符”写入到“PrintStream输出流”中。
    254     private void newLine() {
    255         try {
    256             synchronized (this) {
    257                 ensureOpen();
    258                 textOut.newLine();
    259                 textOut.flushBuffer();
    260                 charOut.flushBuffer();
    261                 if (autoFlush)
    262                     out.flush();
    263             }
    264         }
    265         catch (InterruptedIOException x) {
    266             Thread.currentThread().interrupt();
    267         }
    268         catch (IOException x) {
    269             trouble = true;
    270         }
    271     }
    272 
    273     // 将“boolean数据对应的字符串”写入到“PrintStream输出流”中,print实际调用的是write函数
    274     public void print(boolean b) {
    275         write(b ? "true" : "false");
    276     }
    277 
    278     // 将“字符c对应的字符串”写入到“PrintStream输出流”中,print实际调用的是write函数
    279     public void print(char c) {
    280         write(String.valueOf(c));
    281     }
    282 
    283     // 将“int数据i对应的字符串”写入到“PrintStream输出流”中,print实际调用的是write函数
    284     public void print(int i) {
    285         write(String.valueOf(i));
    286     }
    287 
    288     // 将“long型数据l对应的字符串”写入到“PrintStream输出流”中,print实际调用的是write函数
    289     public void print(long l) {
    290         write(String.valueOf(l));
    291     }
    292 
    293     // 将“float数据f对应的字符串”写入到“PrintStream输出流”中,print实际调用的是write函数
    294     public void print(float f) {
    295         write(String.valueOf(f));
    296     }
    297 
    298     // 将“double数据d对应的字符串”写入到“PrintStream输出流”中,print实际调用的是write函数
    299     public void print(double d) {
    300         write(String.valueOf(d));
    301     }
    302 
    303     // 将“字符数组s”写入到“PrintStream输出流”中,print实际调用的是write函数
    304     public void print(char s[]) {
    305         write(s);
    306     }
    307 
    308     // 将“字符串数据s”写入到“PrintStream输出流”中,print实际调用的是write函数
    309     public void print(String s) {
    310         if (s == null) {
    311             s = "null";
    312         }
    313         write(s);
    314     }
    315 
    316     // 将“对象obj对应的字符串”写入到“PrintStream输出流”中,print实际调用的是write函数
    317     public void print(Object obj) {
    318         write(String.valueOf(obj));
    319     }
    320 
    321 
    322     // 将“换行符”写入到“PrintStream输出流”中,println实际调用的是write函数
    323     public void println() {
    324         newLine();
    325     }
    326 
    327     // 将“boolean数据对应的字符串+换行符”写入到“PrintStream输出流”中,println实际调用的是write函数
    328     public void println(boolean x) {
    329         synchronized (this) {
    330             print(x);
    331             newLine();
    332         }
    333     }
    334 
    335     // 将“字符x对应的字符串+换行符”写入到“PrintStream输出流”中,println实际调用的是write函数
    336     public void println(char x) {
    337         synchronized (this) {
    338             print(x);
    339             newLine();
    340         }
    341     }
    342 
    343     // 将“int数据对应的字符串+换行符”写入到“PrintStream输出流”中,println实际调用的是write函数
    344     public void println(int x) {
    345         synchronized (this) {
    346             print(x);
    347             newLine();
    348         }
    349     }
    350 
    351     // 将“long数据对应的字符串+换行符”写入到“PrintStream输出流”中,println实际调用的是write函数
    352     public void println(long x) {
    353         synchronized (this) {
    354             print(x);
    355             newLine();
    356         }
    357     }
    358 
    359     // 将“float数据对应的字符串+换行符”写入到“PrintStream输出流”中,println实际调用的是write函数
    360     public void println(float x) {
    361         synchronized (this) {
    362             print(x);
    363             newLine();
    364         }
    365     }
    366 
    367     // 将“double数据对应的字符串+换行符”写入到“PrintStream输出流”中,println实际调用的是write函数
    368     public void println(double x) {
    369         synchronized (this) {
    370             print(x);
    371             newLine();
    372         }
    373     }
    374 
    375     // 将“字符数组x+换行符”写入到“PrintStream输出流”中,println实际调用的是write函数
    376     public void println(char x[]) {
    377         synchronized (this) {
    378             print(x);
    379             newLine();
    380         }
    381     }
    382 
    383     // 将“字符串x+换行符”写入到“PrintStream输出流”中,println实际调用的是write函数
    384     public void println(String x) {
    385         synchronized (this) {
    386             print(x);
    387             newLine();
    388         }
    389     }
    390 
    391     // 将“对象o对应的字符串+换行符”写入到“PrintStream输出流”中,println实际调用的是write函数
    392     public void println(Object x) {
    393         String s = String.valueOf(x);
    394         synchronized (this) {
    395             print(s);
    396             newLine();
    397         }
    398     }
    399 
    400     // 将“数据args”根据“默认Locale值(区域属性)”按照format格式化,并写入到“PrintStream输出流”中
    401     public PrintStream printf(String format, Object ... args) {
    402         return format(format, args);
    403     }
    404 
    405     // 将“数据args”根据“Locale值(区域属性)”按照format格式化,并写入到“PrintStream输出流”中
    406     public PrintStream printf(Locale l, String format, Object ... args) {
    407         return format(l, format, args);
    408     }
    409 
    410     // 根据“默认的Locale值(区域属性)”来格式化数据
    411     public PrintStream format(String format, Object ... args) {
    412         try {
    413             synchronized (this) {
    414                 ensureOpen();
    415                 if ((formatter == null)
    416                     || (formatter.locale() != Locale.getDefault()))
    417                     formatter = new Formatter((Appendable) this);
    418                 formatter.format(Locale.getDefault(), format, args);
    419             }
    420         } catch (InterruptedIOException x) {
    421             Thread.currentThread().interrupt();
    422         } catch (IOException x) {
    423             trouble = true;
    424         }
    425         return this;
    426     }
    427 
    428     // 根据“Locale值(区域属性)”来格式化数据
    429     public PrintStream format(Locale l, String format, Object ... args) {
    430         try {
    431             synchronized (this) {
    432                 ensureOpen();
    433                 if ((formatter == null)
    434                     || (formatter.locale() != l))
    435                     formatter = new Formatter(this, l);
    436                 formatter.format(l, format, args);
    437             }
    438         } catch (InterruptedIOException x) {
    439             Thread.currentThread().interrupt();
    440         } catch (IOException x) {
    441             trouble = true;
    442         }
    443         return this;
    444     }
    445 
    446     // 将“字符序列的全部字符”追加到“PrintStream输出流中”
    447     public PrintStream append(CharSequence csq) {
    448         if (csq == null)
    449             print("null");
    450         else
    451             print(csq.toString());
    452         return this;
    453     }
    454 
    455     // 将“字符序列从start(包括)到end(不包括)的全部字符”追加到“PrintStream输出流中”
    456     public PrintStream append(CharSequence csq, int start, int end) {
    457         CharSequence cs = (csq == null ? "null" : csq);
    458         write(cs.subSequence(start, end).toString());
    459         return this;
    460     }
    461 
    462     // 将“字符c”追加到“PrintStream输出流中”
    463     public PrintStream append(char c) {
    464         print(c);
    465         return this;
    466     }
    467 }
    复制代码

    说明
    PrintStream的源码比较简单,请上文的注释进行阅读。若有不明白的地方,建议先看看后面的PrintStream使用示例;待搞清它的作用和用法之后,再来阅读源码。

     

    PrintStream和DataOutputStream异同点

    相同点:都是继承与FileOutputStream,用于包装其它输出流。

    不同点

    (01) PrintStream和DataOutputStream 都可以将数据格式化输出;但它们在“输出字符串”时的编码不同。

           PrintStream是输出时采用的是用户指定的编码(创建PrintStream时指定的),若没有指定,则采用系统默认的字符编码。而DataOutputStream则采用的是UTF-8。
          关于UTF-8的字符编码可以参考“字符编码(ASCII,Unicode和UTF-8) 和 大小端
          关于DataOutputStream的更多内容,可以参考“java io系列15之 DataOutputStream(数据输出流)的认知、源码和示例

    (02) 它们的写入数据时的异常处理机制不同。

           DataOutputStream在通过write()向“输出流”中写入数据时,若产生IOException,会抛出。
           而PrintStream在通过write()向“输出流”中写入数据时,若产生IOException,则会在write()中进行捕获处理;并设置 trouble标记(用于表示产生了异常)为true。用户可以通过checkError()返回trouble值,从而检查输出流中是否产生了异常。

    (03) 构造函数不同

           DataOutputStream的构造函数只有一个:DataOutputStream(OutputStream out)。即它只支持以输出流out作为“DataOutputStream的输出流”。
           而PrintStream的构造函数有许多:和DataOutputStream一样,支持以输出流out作为“PrintStream输出流”的构造函数;还支持以“File对象”或者“String类型的文件名对象”的构造函数。
           而且,在PrintStream的构造函数中,能“指定字符集”和“是否支持自动flush()操作”。

    (04) 目的不同

           DataOutputStream的作用是装饰其它的输出流,它和DataInputStream配合使用:允许应用程序以与机器无关的方式从底层输入流中读写java数据类型。
           而PrintStream的作用虽然也是装饰其他输出流,但是它的目的不是以与机器无关的方式从底层读写java数据类型;而是为其它输出流提供打印各种数据值表示形式,使其它输出流能方便的通过print(), println()或printf()等输出各种格式的数据。

     

    示例代码

    关于PrintStream中API的详细用法,参考示例代码(PrintStreamTest.java)

    复制代码
      1 import java.io.PrintStream;
      2 import java.io.File;
      3 import java.io.FileOutputStream;
      4 import java.io.IOException;
      5 
      6 /**
      7  * PrintStream 的示例程序
      8  *
      9  * @author skywang
     10  */
     11 public class PrintStreamTest {
     12 
     13     public static void main(String[] args) {
     14 
     15         // 下面3个函数的作用都是一样:都是将字母“abcde”写入到文件“file.txt”中。
     16         // 任选一个执行即可!
     17         testPrintStreamConstrutor1() ;
     18         //testPrintStreamConstrutor2() ;
     19         //testPrintStreamConstrutor3() ;
     20 
     21         // 测试write(), print(), println(), printf()等接口。
     22         testPrintStreamAPIS() ;
     23     }
     24 
     25     /**
     26      * PrintStream(OutputStream out) 的测试函数
     27      *
     28      * 函数的作用,就是将字母“abcde”写入到文件“file.txt”中
     29      */
     30     private static void testPrintStreamConstrutor1() {
     31         // 0x61对应ASCII码的字母'a',0x62对应ASCII码的字母'b', ...
     32         final byte[] arr={0x61, 0x62, 0x63, 0x64, 0x65 }; // abced
     33         try {
     34             // 创建文件“file.txt”的File对象
     35             File file = new File("file.txt");
     36             // 创建文件对应FileOutputStream
     37             PrintStream out = new PrintStream(
     38                     new FileOutputStream(file));
     39             // 将“字节数组arr”全部写入到输出流中
     40             out.write(arr);
     41             // 关闭输出流
     42             out.close();
     43         } catch (IOException e) {
     44             e.printStackTrace();
     45         }
     46     }
     47 
     48     /**
     49      * PrintStream(File file) 的测试函数
     50      *
     51      * 函数的作用,就是将字母“abcde”写入到文件“file.txt”中
     52      */
     53     private static void testPrintStreamConstrutor2() {
     54         final byte[] arr={0x61, 0x62, 0x63, 0x64, 0x65 };
     55         try {
     56             File file = new File("file.txt");
     57             PrintStream out = new PrintStream(file);
     58             out.write(arr);
     59             out.close();
     60         } catch (IOException e) {
     61             e.printStackTrace();
     62         }
     63     }
     64 
     65     /**
     66      * PrintStream(String fileName) 的测试函数
     67      *
     68      * 函数的作用,就是将字母“abcde”写入到文件“file.txt”中
     69      */
     70     private static void testPrintStreamConstrutor3() {
     71         final byte[] arr={0x61, 0x62, 0x63, 0x64, 0x65 };
     72         try {
     73             PrintStream out = new PrintStream("file.txt");
     74             out.write(arr);
     75             out.close();
     76         } catch (IOException e) {
     77             e.printStackTrace();
     78         }
     79     }
     80 
     81     /**
     82      * 测试write(), print(), println(), printf()等接口。
     83      */
     84     private static void testPrintStreamAPIS() {
     85         // 0x61对应ASCII码的字母'a',0x62对应ASCII码的字母'b', ...
     86         final byte[] arr={0x61, 0x62, 0x63, 0x64, 0x65 }; // abced
     87         try {
     88             // 创建文件对应FileOutputStream
     89             PrintStream out = new PrintStream("other.txt");
     90 
     91             // 将字符串“hello PrintStream”+回车符,写入到输出流中
     92             out.println("hello PrintStream");
     93             // 将0x41写入到输出流中
     94             // 0x41对应ASCII码的字母'A',也就是写入字符'A'
     95             out.write(0x41);
     96             // 将字符串"65"写入到输出流中。
     97             // out.print(0x41); 等价于 out.write(String.valueOf(0x41));
     98             out.print(0x41);
     99             // 将字符'B'追加到输出流中
    100             out.append('B');
    101 
    102             // 将"CDE is 5" + 回车  写入到输出流中
    103             String str = "CDE";
    104             int num = 5;
    105             out.printf("%s is %d
    ", str, num);
    106 
    107             out.close();
    108         } catch (IOException e) {
    109             e.printStackTrace();
    110         }
    111     }
    112 }
    复制代码

    运行上面的代码,会在源码所在目录生成两个文件“file.txt”和“other.txt”。
    file.txt的内容如下:

    abcde

    other.txt的内容如下:

    hello PrintStream
    A65BCDE is 5

     

  • 相关阅读:
    [转载]每天要说无数次的话,原来英语这么说
    [转载]What I Have Lived For 一生何求?
    WIN 7 和fedora双系统引导问题
    [转载]网站建设中一些容易被忽视的问题
    linux进程控制-wait()
    shell(2)
    电脑英语缩略词
    shell(1)
    [转载]无论成败 但求做最好的自己
    [转载]C++出错提示英汉对照表
  • 原文地址:https://www.cnblogs.com/shangxiaofei/p/3844034.html
Copyright © 2020-2023  润新知