Java 中的Printstream介绍_动力节点Java学院整理
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)
package java.io; import java.util.formatter; import java.util.locale; import java.nio.charset.charset; import java.nio.charset.illegalcharsetnameexception; import java.nio.charset.unsupportedcharsetexception; public class printstream extends filteroutputstream implements appendable, closeable { // 自动flush // 所谓“自动flush”,就是每次执行print(), println(), write()函数,都会调用flush()函数; // 而“不自动flush”,则需要我们手动调用flush()接口。 private final boolean autoflush; // printstream是否右产生异常。当printstream有异常产生时,会被本身捕获,并设置trouble为true private boolean trouble = false; // 用于格式化的对象 private formatter formatter; // bufferedwriter对象,用于实现“printstream支持字符集”。 // 因为printstream是outputstream的子类,所以它本身不支持字符串; // 但是bufferedwriter支持字符集,因此可以通过outputstreamwriter创建printstream对应的bufferedwriter对象,从而支持字符集。 private bufferedwriter textout; private outputstreamwriter charout; private static <t> t requirenonnull(t obj, string message) { if (obj == null) throw new nullpointerexception(message); return obj; } // 返回csn对应的字符集对象 private static charset tocharset(string csn) throws unsupportedencodingexception { requirenonnull(csn, "charsetname"); try { return charset.forname(csn); } catch (illegalcharsetnameexception|unsupportedcharsetexception unused) { // unsupportedencodingexception should be thrown throw new unsupportedencodingexception(csn); } } // 将“输出流out”作为printstream的输出流,autoflush的flush模式,并且采用默认字符集。 private printstream(boolean autoflush, outputstream out) { super(out); this.autoflush = autoflush; this.charout = new outputstreamwriter(this); this.textout = new bufferedwriter(charout); } // 将“输出流out”作为printstream的输出流,自动flush,采用charsetname字符集。 private printstream(boolean autoflush, outputstream out, charset charset) { super(out); this.autoflush = autoflush; this.charout = new outputstreamwriter(this, charset); this.textout = new bufferedwriter(charout); } // 将“输出流out”作为printstream的输出流,自动flush,采用charsetname字符集。 private printstream(boolean autoflush, charset charset, outputstream out) throws unsupportedencodingexception { this(autoflush, out, charset); } // 将“输出流out”作为printstream的输出流,不会自动flush,并且采用默认字符集 public printstream(outputstream out) { this(out, false); } // 将“输出流out”作为printstream的输出流,自动flush,并且采用默认字符集。 public printstream(outputstream out, boolean autoflush) { this(autoflush, requirenonnull(out, "null output stream")); } // 将“输出流out”作为printstream的输出流,自动flush,采用charsetname字符集。 public printstream(outputstream out, boolean autoflush, string encoding) throws unsupportedencodingexception { this(autoflush, requirenonnull(out, "null output stream"), tocharset(encoding)); } // 创建filename对应的fileoutputstream,然后将该fileoutputstream作为printstream的输出流,不自动flush,采用默认字符集。 public printstream(string filename) throws filenotfoundexception { this(false, new fileoutputstream(filename)); } // 创建filename对应的fileoutputstream,然后将该fileoutputstream作为printstream的输出流,不自动flush,采用charsetname字符集。 public printstream(string filename, string csn) throws filenotfoundexception, unsupportedencodingexception { // ensure charset is checked before the file is opened this(false, tocharset(csn), new fileoutputstream(filename)); } // 创建file对应的fileoutputstream,然后将该fileoutputstream作为printstream的输出流,不自动flush,采用默认字符集。 public printstream(file file) throws filenotfoundexception { this(false, new fileoutputstream(file)); } // 创建file对应的fileoutputstream,然后将该fileoutputstream作为printstream的输出流,不自动flush,采用csn字符集。 public printstream(file file, string csn) throws filenotfoundexception, unsupportedencodingexception { // ensure charset is checked before the file is opened this(false, tocharset(csn), new fileoutputstream(file)); } private void ensureopen() throws ioexception { if (out == null) throw new ioexception("stream closed"); } // flush“printstream输出流缓冲中的数据”。 // 例如,printstream装饰的是fileoutputstream,则调用flush时会将数据写入到文件中 public void flush() { synchronized (this) { try { ensureopen(); out.flush(); } catch (ioexception x) { trouble = true; } } } private boolean closing = false; /* to avoid recursive closing */ // 关闭printstream public void close() { synchronized (this) { if (! closing) { closing = true; try { textout.close(); out.close(); } catch (ioexception x) { trouble = true; } textout = null; charout = null; out = null; } } } // flush“printstream输出流缓冲中的数据”,并检查错误 public boolean checkerror() { if (out != null) flush(); if (out instanceof java.io.printstream) { printstream ps = (printstream) out; return ps.checkerror(); } return trouble; } protected void seterror() { trouble = true; } protected void clearerror() { trouble = false; } // 将数据b写入到“printstream输出流”中。b虽然是int类型,但实际只会写入一个字节 public void write(int b) { try { synchronized (this) { ensureopen(); out.write(b); if ((b == '\n') && autoflush) out.flush(); } } catch (interruptedioexception x) { thread.currentthread().interrupt(); } catch (ioexception x) { trouble = true; } } // 将“buf中从off开始的length个字节”写入到“printstream输出流”中。 public void write(byte buf[], int off, int len) { try { synchronized (this) { ensureopen(); out.write(buf, off, len); if (autoflush) out.flush(); } } catch (interruptedioexception x) { thread.currentthread().interrupt(); } catch (ioexception x) { trouble = true; } } // 将“buf中的全部数据”写入到“printstream输出流”中。 private void write(char buf[]) { try { synchronized (this) { ensureopen(); textout.write(buf); textout.flushbuffer(); charout.flushbuffer(); if (autoflush) { for (int i = ; i < buf.length; i++) if (buf[i] == '\n') out.flush(); } } } catch (interruptedioexception x) { thread.currentthread().interrupt(); } catch (ioexception x) { trouble = true; } } // 将“字符串s”写入到“printstream输出流”中。 private void write(string s) { try { synchronized (this) { ensureopen(); textout.write(s); textout.flushbuffer(); charout.flushbuffer(); if (autoflush && (s.indexof('\n') >= )) out.flush(); } } catch (interruptedioexception x) { thread.currentthread().interrupt(); } catch (ioexception x) { trouble = true; } } // 将“换行符”写入到“printstream输出流”中。 private void newline() { try { synchronized (this) { ensureopen(); textout.newline(); textout.flushbuffer(); charout.flushbuffer(); if (autoflush) out.flush(); } } catch (interruptedioexception x) { thread.currentthread().interrupt(); } catch (ioexception x) { trouble = true; } } // 将“boolean数据对应的字符串”写入到“printstream输出流”中,print实际调用的是write函数 public void print(boolean b) { write(b ? "true" : "false"); } // 将“字符c对应的字符串”写入到“printstream输出流”中,print实际调用的是write函数 public void print(char c) { write(string.valueof(c)); } // 将“int数据i对应的字符串”写入到“printstream输出流”中,print实际调用的是write函数 public void print(int i) { write(string.valueof(i)); } // 将“long型数据l对应的字符串”写入到“printstream输出流”中,print实际调用的是write函数 public void print(long l) { write(string.valueof(l)); } // 将“float数据f对应的字符串”写入到“printstream输出流”中,print实际调用的是write函数 public void print(float f) { write(string.valueof(f)); } // 将“double数据d对应的字符串”写入到“printstream输出流”中,print实际调用的是write函数 public void print(double d) { write(string.valueof(d)); } // 将“字符数组s”写入到“printstream输出流”中,print实际调用的是write函数 public void print(char s[]) { write(s); } // 将“字符串数据s”写入到“printstream输出流”中,print实际调用的是write函数 public void print(string s) { if (s == null) { s = "null"; } write(s); } // 将“对象obj对应的字符串”写入到“printstream输出流”中,print实际调用的是write函数 public void print(object obj) { write(string.valueof(obj)); } // 将“换行符”写入到“printstream输出流”中,println实际调用的是write函数 public void println() { newline(); } // 将“boolean数据对应的字符串+换行符”写入到“printstream输出流”中,println实际调用的是write函数 public void println(boolean x) { synchronized (this) { print(x); newline(); } } // 将“字符x对应的字符串+换行符”写入到“printstream输出流”中,println实际调用的是write函数 public void println(char x) { synchronized (this) { print(x); newline(); } } // 将“int数据对应的字符串+换行符”写入到“printstream输出流”中,println实际调用的是write函数 public void println(int x) { synchronized (this) { print(x); newline(); } } // 将“long数据对应的字符串+换行符”写入到“printstream输出流”中,println实际调用的是write函数 public void println(long x) { synchronized (this) { print(x); newline(); } } // 将“float数据对应的字符串+换行符”写入到“printstream输出流”中,println实际调用的是write函数 public void println(float x) { synchronized (this) { print(x); newline(); } } // 将“double数据对应的字符串+换行符”写入到“printstream输出流”中,println实际调用的是write函数 public void println(double x) { synchronized (this) { print(x); newline(); } } // 将“字符数组x+换行符”写入到“printstream输出流”中,println实际调用的是write函数 public void println(char x[]) { synchronized (this) { print(x); newline(); } } // 将“字符串x+换行符”写入到“printstream输出流”中,println实际调用的是write函数 public void println(string x) { synchronized (this) { print(x); newline(); } } // 将“对象o对应的字符串+换行符”写入到“printstream输出流”中,println实际调用的是write函数 public void println(object x) { string s = string.valueof(x); synchronized (this) { print(s); newline(); } } // 将“数据args”根据“默认locale值(区域属性)”按照format格式化,并写入到“printstream输出流”中 public printstream printf(string format, object ... args) { return format(format, args); } // 将“数据args”根据“locale值(区域属性)”按照format格式化,并写入到“printstream输出流”中 public printstream printf(locale l, string format, object ... args) { return format(l, format, args); } // 根据“默认的locale值(区域属性)”来格式化数据 public printstream format(string format, object ... args) { try { synchronized (this) { ensureopen(); if ((formatter == null) || (formatter.locale() != locale.getdefault())) formatter = new formatter((appendable) this); formatter.format(locale.getdefault(), format, args); } } catch (interruptedioexception x) { thread.currentthread().interrupt(); } catch (ioexception x) { trouble = true; } return this; } // 根据“locale值(区域属性)”来格式化数据 public printstream format(locale l, string format, object ... args) { try { synchronized (this) { ensureopen(); if ((formatter == null) || (formatter.locale() != l)) formatter = new formatter(this, l); formatter.format(l, format, args); } } catch (interruptedioexception x) { thread.currentthread().interrupt(); } catch (ioexception x) { trouble = true; } return this; } // 将“字符序列的全部字符”追加到“printstream输出流中” public printstream append(charsequence csq) { if (csq == null) print("null"); else print(csq.tostring()); return this; } // 将“字符序列从start(包括)到end(不包括)的全部字符”追加到“printstream输出流中” public printstream append(charsequence csq, int start, int end) { charsequence cs = (csq == null ? "null" : csq); write(cs.subsequence(start, end).tostring()); return this; } // 将“字符c”追加到“printstream输出流中” public printstream append(char c) { print(c); return this; } }
说明:
printstream的源码比较简单,请上文的注释进行阅读。若有不明白的地方,建议先看看后面的printstream使用示例;待搞清它的作用和用法之后,再来阅读源码。
printstream和dataoutputstream异同点
相同点:都是继承与fileoutputstream,用于包装其它输出流。
不同点:
(01) printstream和dataoutputstream 都可以将数据格式化输出;但它们在“输出字符串”时的编码不同。
printstream是输出时采用的是用户指定的编码(创建printstream时指定的),若没有指定,则采用系统默认的字符编码。而dataoutputstream则采用的是utf-8。
(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):
import java.io.printstream; import java.io.file; import java.io.fileoutputstream; import java.io.ioexception; /** * printstream 的示例程序 * * */ public class printstreamtest { public static void main(string[] args) { // 下面3个函数的作用都是一样:都是将字母“abcde”写入到文件“file.txt”中。 // 任选一个执行即可! testprintstreamconstrutor() ; //testprintstreamconstrutor2() ; //testprintstreamconstrutor3() ; // 测试write(), print(), println(), printf()等接口。 testprintstreamapis() ; } /** * printstream(outputstream out) 的测试函数 * * 函数的作用,就是将字母“abcde”写入到文件“file.txt”中 */ private static void testprintstreamconstrutor() { // 0x61对应ascii码的字母'a',0x62对应ascii码的字母'b', ... final byte[] arr={0x61, 0x62, 0x63, 0x64, 0x65 }; // abced try { // 创建文件“file.txt”的file对象 file file = new file("file.txt"); // 创建文件对应fileoutputstream printstream out = new printstream( new fileoutputstream(file)); // 将“字节数组arr”全部写入到输出流中 out.write(arr); // 关闭输出流 out.close(); } catch (ioexception e) { e.printstacktrace(); } } /** * printstream(file file) 的测试函数 * * 函数的作用,就是将字母“abcde”写入到文件“file.txt”中 */ private static void testprintstreamconstrutor2() { final byte[] arr={0x61, 0x62, 0x63, 0x64, 0x65 }; try { file file = new file("file.txt"); printstream out = new printstream(file); out.write(arr); out.close(); } catch (ioexception e) { e.printstacktrace(); } } /** * printstream(string filename) 的测试函数 * * 函数的作用,就是将字母“abcde”写入到文件“file.txt”中 */ private static void testprintstreamconstrutor3() { final byte[] arr={0x61, 0x62, 0x63, 0x64, 0x65 }; try { printstream out = new printstream("file.txt"); out.write(arr); out.close(); } catch (ioexception e) { e.printstacktrace(); } } /** * 测试write(), print(), println(), printf()等接口。 */ private static void testprintstreamapis() { // 0x61对应ascii码的字母'a',0x62对应ascii码的字母'b', ... final byte[] arr={0x61, 0x62, 0x63, 0x64, 0x65 }; // abced try { // 创建文件对应fileoutputstream printstream out = new printstream("other.txt"); // 将字符串“hello printstream”+回车符,写入到输出流中 out.println("hello printstream"); // 将x写入到输出流中 // x对应ascii码的字母'a',也就是写入字符'a' out.write(0x41); // 将字符串"65"写入到输出流中。 // out.print(0x41); 等价于 out.write(string.valueof(0x41)); out.print(0x41); // 将字符'b'追加到输出流中 out.append('b'); // 将"cde is 5" + 回车 写入到输出流中 string str = "cde"; int num = 5; out.printf("%s is %d\n", str, num); out.close(); } catch (ioexception e) { e.printstacktrace(); } } }
运行上面的代码,会在源码所在目录生成两个文件“file.txt”和“other.txt”。
file.txt的内容如下:
abcde
other.txt的内容如下:
hello printstream a65bcde is 5
以上所述是小编给大家介绍的java 中的printstream知识,希望对大家有所帮助
推荐阅读