java的PrintStream(打印输出流)详解(java_io)
java的PrintStream(打印输出流)详解(java_io)
本章介绍PrintStream以及 它与DataOutputStream的区别。我们先对PrintStream有个大致认识,然后再深入学习它的源码,最后通过示例加深对它的了解。
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 == '\n') && 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] == '\n')
- 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('\n') >= 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\n", 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
java的PrintStream(打印输出流)详解(java_io)的更多相关文章
- java io系列16之 PrintStream(打印输出流)详解
本章介绍PrintStream以及 它与DataOutputStream的区别.我们先对PrintStream有个大致认识,然后再深入学习它的源码,最后通过示例加深对它的了解. 转载请注明出处:htt ...
- Java中PrintStream(打印输出流)
Java中PrintStream(打印输出流) PrintStream 是打印输出流,它继承于FilterOutputStream. PrintStream 是用来装饰其它输出流.它能为其他输出流 ...
- Java I/O输入输出流详解
一.文件的编码 开发时一定要注意项目默认的编码!!!!!!!! 文件操作的时候一定要记得关闭!!!!!!!! ASCII:美国标准 ...
- java中的io系统详解 - ilibaba的专栏 - 博客频道 - CSDN.NET
java中的io系统详解 - ilibaba的专栏 - 博客频道 - CSDN.NET 亲,“社区之星”已经一周岁了! 社区福利快来领取免费参加MDCC大会机会哦 Tag功能介绍—我们 ...
- Java网络编程和NIO详解2:JAVA NIO一步步构建IO多路复用的请求模型
Java网络编程与NIO详解2:JAVA NIO一步步构建IO多路复用的请求模型 知识点 nio 下 I/O 阻塞与非阻塞实现 SocketChannel 介绍 I/O 多路复用的原理 事件选择器与 ...
- Java中的main()方法详解
在Java中,main()方法是Java应用程序的入口方法,也就是说,程序在运行的时候,第一个执行的方法就是main()方法,这个方法和其他的方法有很大的不同,比如方法的名字必须是main,方法必须是 ...
- Java面试题04-final关键字详解
Java面试题04-final关键字详解 本篇博客将会讨论java中final关键字的含义,以及final用在什么地方,感觉看书总会有一些模糊,而且解释的不是很清楚,在此做个总结,以备准备面试的时候查 ...
- Java I/O : Java中的进制详解
作者:李强强 上一篇,泥瓦匠基础地讲了下Java I/O : Bit Operation 位运算.这一讲,泥瓦匠带你走进Java中的进制详解. 一.引子 在Java世界里,99%的工作都是处理这高层. ...
- Java网络编程和NIO详解开篇:Java网络编程基础
Java网络编程和NIO详解开篇:Java网络编程基础 计算机网络编程基础 转自:https://mp.weixin.qq.com/s/XXMz5uAFSsPdg38bth2jAA 我们是幸运的,因为 ...
随机推荐
- 【Linux】centos7 添加脚本到/etc/rc.local文件里,实现开机自启
Linux 设置开机自启动,添加命令到/etc/rc.d/rc.local,本文以设置tomcat自启动为例: 一:添加自启动命令 export JAVA_HOME=/usr/java/jdk1.8. ...
- elk大纲
一.ELK功能概览 1.检索 2.数据可视化--实时监控(实时刷新) nginx 访问量 ip地区分布图(大数据) 3.zabbix 微信联动报警 4.大数据日志分析平台(基于hadoop) 二.ka ...
- CentOS下安装微软雅黑字体
CentOS下安装微软雅黑字体 微软雅黑下载地址:http://download.csdn.net/detail/u012547633/9796219 1.先从你本机 C:\Windows\Fon ...
- 【Hadoop】二、HDFS文件读写流程
(二)HDFS数据流 作为一个文件系统,文件的读和写是最基本的需求,这一部分我们来了解客户端是如何与HDFS进行交互的,也就是客户端与HDFS,以及构成HDFS的两类节点(namenode和dat ...
- [luogu3067 USACO12OPEN] 平衡的奶牛群
传送门 Solution 折半搜索模板题 考虑枚举每个点在左集合和右集合或者不在集合中,然后排序合并即可 Code //By Menteur_Hxy #include <cmath> #i ...
- 运行/调试你的PHP代码
前言 没有任何一名程序员可以一气呵成.完美无缺的在不用调试的情况下完成一个功能或模块.调试实际分很多种情况.本篇文章我分享下自己在实际开发工作中的经验,我个人理解,调试分三种,注意我所讲的是调试并非测 ...
- Bazinga HDU 5510 Bazinga(双指针)
Bazinga HDU 5510 Bazinga(双指针) 题链 解法:对于串i来说,如果串i是不符合的,那么代表串i之前的字符串都是i的子串,那么我们求一个新的i(定义为ti),如果i是ti 的子串 ...
- BZOJ 2095 [POI2010]Bridges (最大流、欧拉回路)
洛谷上有这题,但是输出方案缺SPJ..(而且我也懒得输出方案了) 题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=2095 题解: 首先判 ...
- 【Codeforces 242C】King's Path
[链接] 我是链接,点我呀:) [题意] 让你找到(x0,y0)到(x1,y1)的一条最短路 走过的点必须在所给的n个横向路径上 [题解] 因为n条横向路径上的点最多不会超过10的5次方个,所以我们可 ...
- HDU 1249 三角形的分割
可以将三角形的三条边一条一条加进图形中观察 假设添加第n个三角形 前n-1个三角形将区域划分为sum[n-1] 第n个三角形每条边最多能经过前n-1个三角形每条三角形的两条边 , 一条边切完增加了 2 ...