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 classPrintStream extends FilterOutputStream
implements Appendable, Closeable
{//自动flush//所谓“自动flush”,就是每次执行print(), println(), write()函数,都会调用flush()函数;//而“不自动flush”,则需要我们手动调用flush()接口。
privatefinal boolean autoFlush;//PrintStream是否右产生异常。当PrintStream有异常产生时,会被本身捕获,并设置trouble为true
private boolean trouble = false;//用于格式化的对象
privateFormatter formatter;//BufferedWriter对象,用于实现“PrintStream支持字符集”。//因为PrintStream是OutputStream的子类,所以它本身不支持字符串;//但是BufferedWriter支持字符集,因此可以通过OutputStreamWriter创建PrintStream对应的BufferedWriter对象,从而支持字符集。
privateBufferedWriter textOut;privateOutputStreamWriter charOut;private static T requireNonNull(T obj, String message) {if (obj == null)throw newNullPointerException(message);returnobj;
}//返回csn对应的字符集对象
private staticCharset toCharset(String csn)
throws UnsupportedEncodingException
{
requireNonNull(csn,"charsetName");try{returnCharset.forName(csn);
}catch (IllegalCharsetNameException|UnsupportedCharsetException unused) {//UnsupportedEncodingException should be thrown
throw newUnsupportedEncodingException(csn);
}
}//将“输出流out”作为PrintStream的输出流,autoFlush的flush模式,并且采用默认字符集。
private PrintStream(boolean autoFlush, OutputStream out) {
super(out);this.autoFlush =autoFlush;this.charOut = new OutputStreamWriter(this);this.textOut = newBufferedWriter(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 = newBufferedWriter(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,采用默认字符集。
publicPrintStream(String fileName) throws FileNotFoundException {this(false, newFileOutputStream(fileName));
}//创建fileName对应的FileOutputStream,然后将该FileOutputStream作为PrintStream的输出流,不自动flush,采用charsetName字符集。
publicPrintStream(String fileName, String csn)
throws FileNotFoundException, UnsupportedEncodingException
{//ensure charset is checked before the file is opened
this(false, toCharset(csn), newFileOutputStream(fileName));
}//创建file对应的FileOutputStream,然后将该FileOutputStream作为PrintStream的输出流,不自动flush,采用默认字符集。
publicPrintStream(File file) throws FileNotFoundException {this(false, newFileOutputStream(file));
}//创建file对应的FileOutputStream,然后将该FileOutputStream作为PrintStream的输出流,不自动flush,采用csn字符集。
publicPrintStream(File file, String csn)
throws FileNotFoundException, UnsupportedEncodingException
{//ensure charset is checked before the file is opened
this(false, toCharset(csn), newFileOutputStream(file));
}private voidensureOpen() throws IOException {if (out == null)throw new IOException("Stream closed");
}//flush“PrintStream输出流缓冲中的数据”。//例如,PrintStream装饰的是FileOutputStream,则调用flush时会将数据写入到文件中
public voidflush() {
synchronized (this) {try{
ensureOpen();out.flush();
}catch(IOException x) {
trouble= true;
}
}
}private boolean closing = false; /*To avoid recursive closing*/
//关闭PrintStream
public voidclose() {
synchronized (this) {if (!closing) {
closing= true;try{
textOut.close();out.close();
}catch(IOException x) {
trouble= true;
}
textOut= null;
charOut= null;out = null;
}
}
}//flush“PrintStream输出流缓冲中的数据”,并检查错误
publicboolean checkError() {if (out != null)
flush();if (outinstanceof java.io.PrintStream) {
PrintStream ps= (PrintStream) out;returnps.checkError();
}returntrouble;
}protected voidsetError() {
trouble= true;
}protected voidclearError() {
trouble= false;
}//将数据b写入到“PrintStream输出流”中。b虽然是int类型,但实际只会写入一个字节
public void write(intb) {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, intlen) {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(charbuf[]) {try{
synchronized (this) {
ensureOpen();
textOut.write(buf);
textOut.flushBuffer();
charOut.flushBuffer();if(autoFlush) {for (int i = 0; i < buf.length; i++)if (buf[i] == '\n')out.flush();
}
}
}catch(InterruptedIOException x) {
Thread.currentThread().interrupt();
}catch(IOException x) {
trouble= true;
}
}//将“字符串s”写入到“PrintStream输出流”中。
private voidwrite(String s) {try{
synchronized (this) {
ensureOpen();
textOut.write(s);
textOut.flushBuffer();
charOut.flushBuffer();if (autoFlush && (s.indexOf('\n') >= 0))out.flush();
}
}catch(InterruptedIOException x) {
Thread.currentThread().interrupt();
}catch(IOException x) {
trouble= true;
}
}//将“换行符”写入到“PrintStream输出流”中。
private voidnewLine() {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 voidprint(boolean b) {
write(b? "true" : "false");
}//将“字符c对应的字符串”写入到“PrintStream输出流”中,print实际调用的是write函数
public void print(charc) {
write(String.valueOf(c));
}//将“int数据i对应的字符串”写入到“PrintStream输出流”中,print实际调用的是write函数
public void print(inti) {
write(String.valueOf(i));
}//将“long型数据l对应的字符串”写入到“PrintStream输出流”中,print实际调用的是write函数
public void print(longl) {
write(String.valueOf(l));
}//将“float数据f对应的字符串”写入到“PrintStream输出流”中,print实际调用的是write函数
public void print(floatf) {
write(String.valueOf(f));
}//将“double数据d对应的字符串”写入到“PrintStream输出流”中,print实际调用的是write函数
public void print(doubled) {
write(String.valueOf(d));
}//将“字符数组s”写入到“PrintStream输出流”中,print实际调用的是write函数
public void print(chars[]) {
write(s);
}//将“字符串数据s”写入到“PrintStream输出流”中,print实际调用的是write函数
public voidprint(String s) {if (s == null) {
s= "null";
}
write(s);
}//将“对象obj对应的字符串”写入到“PrintStream输出流”中,print实际调用的是write函数
public voidprint(Object obj) {
write(String.valueOf(obj));
}//将“换行符”写入到“PrintStream输出流”中,println实际调用的是write函数
public voidprintln() {
newLine();
}//将“boolean数据对应的字符串+换行符”写入到“PrintStream输出流”中,println实际调用的是write函数
public voidprintln(boolean x) {
synchronized (this) {
print(x);
newLine();
}
}//将“字符x对应的字符串+换行符”写入到“PrintStream输出流”中,println实际调用的是write函数
public void println(charx) {
synchronized (this) {
print(x);
newLine();
}
}//将“int数据对应的字符串+换行符”写入到“PrintStream输出流”中,println实际调用的是write函数
public void println(intx) {
synchronized (this) {
print(x);
newLine();
}
}//将“long数据对应的字符串+换行符”写入到“PrintStream输出流”中,println实际调用的是write函数
public void println(longx) {
synchronized (this) {
print(x);
newLine();
}
}//将“float数据对应的字符串+换行符”写入到“PrintStream输出流”中,println实际调用的是write函数
public void println(floatx) {
synchronized (this) {
print(x);
newLine();
}
}//将“double数据对应的字符串+换行符”写入到“PrintStream输出流”中,println实际调用的是write函数
public void println(doublex) {
synchronized (this) {
print(x);
newLine();
}
}//将“字符数组x+换行符”写入到“PrintStream输出流”中,println实际调用的是write函数
public void println(charx[]) {
synchronized (this) {
print(x);
newLine();
}
}//将“字符串x+换行符”写入到“PrintStream输出流”中,println实际调用的是write函数
public voidprintln(String x) {
synchronized (this) {
print(x);
newLine();
}
}//将“对象o对应的字符串+换行符”写入到“PrintStream输出流”中,println实际调用的是write函数
public voidprintln(Object x) {
String s=String.valueOf(x);
synchronized (this) {
print(s);
newLine();
}
}//将“数据args”根据“默认Locale值(区域属性)”按照format格式化,并写入到“PrintStream输出流”中
publicPrintStream printf(String format, Object ... args) {returnformat(format, args);
}//将“数据args”根据“Locale值(区域属性)”按照format格式化,并写入到“PrintStream输出流”中
publicPrintStream printf(Locale l, String format, Object ... args) {returnformat(l, format, args);
}//根据“默认的Locale值(区域属性)”来格式化数据
publicPrintStream 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值(区域属性)”来格式化数据
publicPrintStream 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输出流中”
publicPrintStream append(CharSequence csq) {if (csq == null)
print("null");elseprint(csq.toString());return this;
}//将“字符序列从start(包括)到end(不包括)的全部字符”追加到“PrintStream输出流中”
public PrintStream append(CharSequence csq, int start, intend) {
CharSequence cs= (csq == null ? "null": csq);
write(cs.subSequence(start, end).toString());return this;
}//将“字符c”追加到“PrintStream输出流中”
public PrintStream append(charc) {
print(c);return this;
}
}