java printwriter 包_【java I/O流总结】PrintWriter总结

PrintWriter是字符输出流一个重要的方法,其源码非常简单易懂。下面基于源码来分析PrintWriter跟之前的BufferWriter、FileWriter之间的区别。

构造函数

public PrintWriter(Writer out,

boolean autoFlush) {

super(out);

this.out = out;

this.autoFlush = autoFlush;

lineSeparator = java.security.AccessController.doPrivileged(

new sun.security.action.GetPropertyAction("line.separator"));

}

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可以用来包装Writer的任意子类,当包装OutputStream时,默认包装一层BufferWriter。当然也可以将File或者File路径作为参数,实质上一样,如下所示:

public PrintWriter(String fileName) throws FileNotFoundException {

this(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName))),

false);

}

/* Private constructor */

private PrintWriter(Charset charset, File file)

throws FileNotFoundException

{

this(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), charset)),

false);

}

构造函数里的autoFlush参数默认是false,当设置true时开启自动刷新,当运行println()/printf()/format()方法时,会自动刷新缓冲区。

输出方法

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;

}

}

如果包装了BufferWriter,则out.write(s, off, len)这一行直接转至BufferWriter的对应方法。其它char、char[]格式参数的重载方法大同小异。

输出格式化

PrintWriter中增添了许多数据格式化的代码,即兼容不同类型的变量,float、int等等,如下所示:

public void print(Object obj) {

write(String.valueOf(obj));

}

public void print(double d) {

write(String.valueOf(d));

}

实际上都是使用String.valueOf()将其转化成String,实现不同类型数据的兼容。除此之外,还对每种类型变量实现了println()功能,即换行,如下:

public void println() {

newLine();

}

public void println(long x) {

synchronized (lock) {

print(x);

println();

}

}

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;

}

}

newLine()输出换行,同时执行out.flush()刷新缓冲区。

PrintWriter还提供了printf方法,支持指定格式的输出,实则调用的是format方法,如下:

//Locale l表示语言地区

public PrintWriter printf(Locale l, String format, Object ... args) {

return format(l, format, 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;

}

同样,执行format的过程中也会造成缓冲区刷新(若autoFlush为true)。

注意:若PrintWriter没有包装BufferWriter 譬如直接包装FileWriter,这样缓冲区直接调用StreamEncoder中的flush刷新字节缓冲区;若用了BufferWriter,则调起BufferWriter中的flush函数,先刷新字符缓冲区,再同样刷新StreamEncoder中的字节缓冲区。

异常处理

PrintWriter不会抛出异常,也不需要在外部处理异常,观察前面的write函数可知,方法内部已经做了try catch操作,同时维护了一个trouble布尔变量,可利用它告知外部是否有异常。例如checkError()方法。同时与之相对应的,有setError()和clearError()方法。

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();

}

return trouble;

}

protected void setError() {

trouble = true;

}

protected void clearError() {

trouble = false;

}

append与write区别

PrintWriter中有两个append方法,如下:

public PrintWriter append(CharSequence csq) {

if (csq == null)

write("null");

else

write(csq.toString());

return this;

}

public PrintWriter append(CharSequence csq, int start, int end) {

CharSequence cs = (csq == null ? "null" : csq);

write(cs.subSequence(start, end).toString());

return this;

}

感觉这个append没什么用,跟write的区别在于,参数可以传入null,还有参数是CharSequence类型字符序列(String,StringBuilder,StringBuffer都实现了这个接口)。

PrintWriter特点总结

可以兼容多种变量类型的输出,可用printf自定义输出格式,也可用println换行输出;

设置autoflush为true时,可在换行或者format时自动刷新缓冲区;

不会抛出异常。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值