今天来学习PrintWriter。
PrintWriter,字符类型的打印输出流,用于控制文本输出流打印对象的格式化表示形式。此类实现在PrintStream中的所有print方法。它不包含用于写入原始字节的方法。
此类中的方法不会抛出I/O异常,尽管其某些构造方法可能抛出异常。客户端可能会查询调用checkError()是否出现错误。
ps:如果不想看源码,文章末尾有对源码的总结。
源码下面看下PrintWriter的源码。
public class PrintWriter extends Writer { /** * PrintWriter的底层字符输出流 */ protected Writer out; //是否自动刷新。 //如果为true,每次执行print(), println(), write()函数,都会调用flush()函数。 private final boolean autoFlush; //是否有异常 //当PrintWriter有异常产生时,会被本身捕获,并设置trouble为true private boolean trouble = false; //用于格式化字符串的对象 private Formatter formatter; //字节打印流 //用于checkError方法 private PrintStream psOut = null; /** * 行分隔符 * 在PrintWriter被创建时line.separator属性的值。 */ private final String lineSeparator; /** * 返回csn(字符集名字)对应的Chaset * csn为null或是不支持的字符集,抛出异常 */ private static Charset toCharset(String csn) throws UnsupportedEncodingException { Objects.requireNonNull(csn, "charsetName"); try { return Charset.forName(csn); } catch (IllegalCharsetNameException|UnsupportedCharsetException unused) { // UnsupportedEncodingException should be thrown throw new UnsupportedEncodingException(csn); } } /** * 创建新的PrintWriter。 * 指定底层输出流,默认不会自动flush,采用默认字符集 */ public PrintWriter (Writer out) { this(out, false); } /** * 创建新的PrintWriter。 * 指定底层输出流,指定是否自动flush,采用默认字符集 */ public PrintWriter(Writer out, boolean autoFlush) { super(out); this.out = out; this.autoFlush = autoFlush; //line.separator属性的值 lineSeparator = java.security.AccessController.doPrivileged( new sun.security.action.GetPropertyAction("line.separator")); } /** * 创建新的PrintWriter。 * 指定底层输出流,不自动flush,采用默认字符集 */ public PrintWriter(OutputStream out) { this(out, false); } /** * 创建新的PrintWriter。 * 指定底层输出流,指定是否自动flush,采用默认字符集 */ public PrintWriter(OutputStream out, boolean autoFlush) { this(new BufferedWriter(new OutputStreamWriter(out)), autoFlush); // save print stream for error propagation if (out instanceof java.io.PrintStream) { psOut = (PrintStream) out; } } /** * 创建新的PrintWriter。 * 指定文件名,默认不自动flush,采用默认字符集 */ public PrintWriter(String fileName) throws FileNotFoundException { this(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName))), false); } /** * 私有构造方法。创建新的PrintWriter。 * 指定文件名,默认不自动flush,采用指定字符集 */ private PrintWriter(Charset charset, File file) throws FileNotFoundException { this(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), charset)), false); } /** * 创建新的PrintWriter。 * 指定文件名,默认不自动flush,采用指定字符集 */ public PrintWriter(String fileName, String csn) throws FileNotFoundException, UnsupportedEncodingException { this(toCharset(csn), new File(fileName)); } /** * 创建新的PrintWriter。 * 指定文件名,默认不自动flush,采用默认字符集 */ public PrintWriter(File file) throws FileNotFoundException { this(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file))), false); } /** * 创建新的PrintWriter。 * 指定文件名,默认不自动flush,采用指定字符集 */ public PrintWriter(File file, String csn) throws FileNotFoundException, UnsupportedEncodingException { this(toCharset(csn), file); } /** 确认输出流是否开启。如果底层输出流不为null,则认为输出流是开启的 */ private void ensureOpen() throws IOException { if (out == null) throw new IOException("Stream closed"); } /** * 刷新流 * @see #checkError() */ public void flush() { try { synchronized (lock) { ensureOpen(); out.flush(); } } catch (IOException x) { //当PrintWriter有异常产生时,会被本身捕获,并设置trouble为true trouble = true; } } /** * 关闭该流并释放与之关联的所有系统资源。 * 将底层输出流置为null,就把输出流关闭了 * * @see #checkError() */ public void close() { try { synchronized (lock) { if (out == null) return; out.close(); out = null; } } catch (IOException x) { trouble = true; } } /** * 如果流没有关闭,则刷新流且检查其错误状态。 */ public boolean checkError() { //如果流没有关闭,则刷新流 if (out != null) { flush(); } //检查错误状态 if (out instanceof java.io.PrintWriter) { PrintWriter pw = (PrintWriter) out; return pw.checkError(); } else if (psOut != null) { return psOut.checkError(); } //如果抛出了异常,返回true return trouble; } /** * 指示已发生错误。 * 在调用clearError()之前,此方法将导致checkError()的后续调用返回 true。 */ protected void setError() { trouble = true; } /** * 清除此流的错误状态。 */ protected void clearError() { trouble = false; } /** * 写入单个字符。 */ public void write(int c) { try { synchronized (lock) { ensureOpen(); //调用底层输出流写入单个字符 out.write(c); } } catch (InterruptedIOException x) { Thread.currentThread().interrupt(); } catch (IOException x) { trouble = true; } } /** * 写入字符数组的某一部分。 */ public void write(char buf[], int off, int len) { try { synchronized (lock) { ensureOpen(); //调用底层输出流写入字符数组的某一部分 out.write(buf, off, len); } } catch (InterruptedIOException x) { Thread.currentThread().interrupt(); } catch (IOException x) { trouble = true; } } /** * 写入字符数组。 * 此方法不能从Writer类继承,因为它必须取消I/O异常。 */ public void write(char buf[]) { write(buf, 0, buf.length); } /** * 写入字符串的某一部分。 */ public void write(String s, int off, int len) { try { synchronized (lock) { ensureOpen(); out.write(s, off, len); } } catch (InterruptedIOException x) { Thread.currentThread().interrupt(); } catch (IOException x) { trouble = true; } } /** * 写入字符串。 * 此方法不能从Writer类继承,因为它必须取消I/O异常。 */ public void write(String s) { write(s, 0, s.length()); } //写入换行符 private void newLine() { try { synchronized (lock) { ensureOpen(); out.write(lineSeparator); if (autoFlush) out.flush(); } } catch (InterruptedIOException x) { Thread.currentThread().interrupt(); } catch (IOException x) { trouble = true; } } /* Methods that do not terminate lines */ /** * 打印boolean值。 * 按照平台的默认字符编码将字符串转换为字节,然后写入输出流。 */ public void print(boolean b) { write(b ? "true" : "false"); } /** * 打印字符。 */ public void print(char c) { write(c); } /** * 打印整数。 * 按照平台的默认字符编码将字符串转换为字节,然后写入输出流。 */ public void print(int i) { write(String.valueOf(i)); } /** * 打印long。 * 按照平台的默认字符编码将字符串转换为字节,然后写入输出流。 */ public void print(long l) { write(String.valueOf(l)); } /** * 打印一个浮点数。 * 按照平台的默认字符编码将字符串转换为字节,然后写入输出流。 */ public void print(float f) { write(String.valueOf(f)); } /** * 打印double精度浮点数。 * 按照平台的默认字符编码将字符串转换为字节,然后写入输出流。 */ public void print(double d) { write(String.valueOf(d)); } /** * 打印字符数组。 * 按照平台的默认字符编码将字符转换为字节,然后写入输出流。 */ public void print(char s[]) { write(s); } /** * 打印字符串。 * 如果参数为null,则打印字符串"null" * 否则,按照平台的默认字符编码将字符串的字符转换为字节,然后写入输出流。 */ public void print(String s) { if (s == null) { s = "null"; } write(s); } /** * 打印对象。 * 按照平台的默认字符串编码将String.valueOf(Object)方法生成的字符串转换为字节, * 并完全以 write(int) 方法的方式写入这些字节。 */ public void print(Object obj) { write(String.valueOf(obj)); } /* Methods that do terminate lines */ /** * 通过写入行分隔符字符串终止当前行。 * 行分隔符字符串由系统属性line.separator定义,不一定是单个换行符('\n')。 */ public void println() { newLine(); } /** * 打印boolean值,然后终止该行。 */ public void println(boolean x) { synchronized (lock) { print(x); println(); } } /** * 打印字符,然后终止该行。 */ public void println(char x) { synchronized (lock) { print(x); println(); } } /** * 打印整数,然后终止该行。 */ public void println(int x) { synchronized (lock) { print(x); println(); } } /** * 打印long整数,然后终止该行。 */ public void println(long x) { synchronized (lock) { print(x); println(); } } /** * 打印浮点数,然后终止该行。 */ public void println(float x) { synchronized (lock) { print(x); println(); } } /** * 打印双精度浮点数,然后终止该行。 */ public void println(double x) { synchronized (lock) { print(x); println(); } } /** * 打印字符数组,然后终止该行。 */ public void println(char x[]) { synchronized (lock) { print(x); println(); } } /** * 打印String,然后终止该行。 */ public void println(String x) { synchronized (lock) { print(x); println(); } } /** * 打印Object,然后终止该行。 */ public void println(Object x) { String s = String.valueOf(x); synchronized (lock) { print(s); println(); } } /** * 使用指定格式字符串和参数将一个格式化字符串写入此writer中。 * 如果启用自动刷新,则调用此方法将刷新输出缓冲区。 * * @param format 在格式字符串的语法中描述的格式字符串。 * 格式字符串的语法可以参考http://tool.oschina.net/uploads/ ... rmatter.html#syntax * * @param args * 格式字符串中的格式说明符引用的参数。如果参数多于格式说明符,则忽略额外的参数。参数的数量是可变的,并且可以为零。 * * @since 1.5 */ public PrintWriter printf(String format, Object ... args) { return format(format, args); } /** * 使用指定格式字符串和参数将一个格式化字符串写入此writer中。 * 如果启用自动刷新,则调用此方法将刷新输出缓冲区。 * * @param l * 格式化过程中应用的locale。如果l为null,则不应用本地化。 * * @param format * 在格式字符串的语法中描述的格式字符串。 * * @param args * 格式字符串中的格式说明符引用的参数。 * * @since 1.5 */ public PrintWriter printf(Locale l, String format, Object ... args) { return format(l, format, args); } /** * 参考public PrintWriter printf(String format, Object... args) */ public PrintWriter format(String format, Object ... args) { try { synchronized (lock) { ensureOpen(); if ((formatter == null) || (formatter.locale() != Locale.getDefault())) formatter = new Formatter(this); formatter.format(Locale.getDefault(), format, args); if (autoFlush) out.flush(); } } catch (InterruptedIOException x) { Thread.currentThread().interrupt(); } catch (IOException x) { trouble = true; } return this; } /** * 参考printf(Locale l, String format, Object... args) */ public PrintWriter format(Locale l, String format, Object ... args) { try { synchronized (lock) { ensureOpen(); if ((formatter == null) || (formatter.locale() != l)) formatter = new Formatter(this, l); formatter.format(l, format, args); if (autoFlush) out.flush(); } } catch (InterruptedIOException x) { Thread.currentThread().interrupt(); } catch (IOException x) { trouble = true; } return this; } /** * 将指定的字符序列添加到此writer。 * 可能不添加整个序列,也可能添加,具体取决于字符序列csq的toString指定。 * * @since 1.5 */ public PrintWriter append(CharSequence csq) { if (csq == null) write("null"); else write(csq.toString()); return this; } /** * 将指定字符序列的子序列添加到此writer。 * * @since 1.5 */ public PrintWriter append(CharSequence csq, int start, int end) { CharSequence cs = (csq == null ? "null" : csq); write(cs.subSequence(start, end).toString()); return this; } /** * 将指定字符添加到此 writer。 * * @since 1.5 */ public PrintWriter append(char c) { write(c); return this; }}关于PrintWriter就讲到这里,想了解更多内容请参考
| 欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) | 黑马程序员IT技术论坛 X3.2 |