1. /*
  2. * @(#)PrintStream.java 1.25 03/01/23
  3. *
  4. * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.io;
  8. /**
  9. * A <code>PrintStream</code> adds functionality to another output stream,
  10. * namely the ability to print representations of various data values
  11. * conveniently. Two other features are provided as well. Unlike other output
  12. * streams, a <code>PrintStream</code> never throws an
  13. * <code>IOException</code> instead, exceptional situations merely set an
  14. * internal flag that can be tested via the <code>checkError</code> method.
  15. * Optionally, a <code>PrintStream</code> can be created so as to flush
  16. * automatically; this means that the <code>flush</code> method is
  17. * automatically invoked after a byte array is written, one of the
  18. * <code>println</code> methods is invoked, or a newline character or byte
  19. * (<code>'\n'</code>) is written.
  20. *
  21. * <p> All characters printed by a <code>PrintStream</code> are converted into
  22. * bytes using the platform's default character encoding. The <code>{@link
  23. * PrintWriter}</code> class should be used in situations that require writing
  24. * characters rather than bytes.
  25. *
  26. * @version 1.25, 03/01/23
  27. * @author Frank Yellin
  28. * @author Mark Reinhold
  29. * @since JDK1.0
  30. */
  31. public class PrintStream extends FilterOutputStream {
  32. private boolean autoFlush = false;
  33. private boolean trouble = false;
  34. /**
  35. * Track both the text- and character-output streams, so that their buffers
  36. * can be flushed without flushing the entire stream.
  37. */
  38. private BufferedWriter textOut;
  39. private OutputStreamWriter charOut;
  40. /**
  41. * Create a new print stream. This stream will not flush automatically.
  42. *
  43. * @param out The output stream to which values and objects will be
  44. * printed
  45. *
  46. * @see java.io.PrintWriter#PrintWriter(java.io.OutputStream)
  47. */
  48. public PrintStream(OutputStream out) {
  49. this(out, false);
  50. }
  51. /* Initialization is factored into a private constructor (note the swapped
  52. * parameters so that this one isn't confused with the public one) and a
  53. * separate init method so that the following two public constructors can
  54. * share code. We use a separate init method so that the constructor that
  55. * takes an encoding will throw an NPE for a null stream before it throws
  56. * an UnsupportedEncodingException for an unsupported encoding.
  57. */
  58. private PrintStream(boolean autoFlush, OutputStream out)
  59. {
  60. super(out);
  61. if (out == null)
  62. throw new NullPointerException("Null output stream");
  63. this.autoFlush = autoFlush;
  64. }
  65. private void init(OutputStreamWriter osw) {
  66. this.charOut = osw;
  67. this.textOut = new BufferedWriter(osw);
  68. }
  69. /**
  70. * Create a new print stream.
  71. *
  72. * @param out The output stream to which values and objects will be
  73. * printed
  74. * @param autoFlush A boolean; if true, the output buffer will be flushed
  75. * whenever a byte array is written, one of the
  76. * <code>println</code> methods is invoked, or a newline
  77. * character or byte (<code>'\n'</code>) is written
  78. *
  79. * @see java.io.PrintWriter#PrintWriter(java.io.OutputStream, boolean)
  80. */
  81. public PrintStream(OutputStream out, boolean autoFlush) {
  82. this(autoFlush, out);
  83. init(new OutputStreamWriter(this));
  84. }
  85. /**
  86. * Create a new print stream.
  87. *
  88. * @param out The output stream to which values and objects will be
  89. * printed
  90. * @param autoFlush A boolean; if true, the output buffer will be flushed
  91. * whenever a byte array is written, one of the
  92. * <code>println</code> methods is invoked, or a newline
  93. * character or byte (<code>'\n'</code>) is written
  94. * @param encoding The name of a supported
  95. * <a href="../lang/package-summary.html#charenc">
  96. * character encoding</a>
  97. *
  98. * @exception UnsupportedEncodingException
  99. * If the named encoding is not supported
  100. */
  101. public PrintStream(OutputStream out, boolean autoFlush, String encoding)
  102. throws UnsupportedEncodingException
  103. {
  104. this(autoFlush, out);
  105. init(new OutputStreamWriter(this, encoding));
  106. }
  107. /** Check to make sure that the stream has not been closed */
  108. private void ensureOpen() throws IOException {
  109. if (out == null)
  110. throw new IOException("Stream closed");
  111. }
  112. /**
  113. * Flush the stream. This is done by writing any buffered output bytes to
  114. * the underlying output stream and then flushing that stream.
  115. *
  116. * @see java.io.OutputStream#flush()
  117. */
  118. public void flush() {
  119. synchronized (this) {
  120. try {
  121. ensureOpen();
  122. out.flush();
  123. }
  124. catch (IOException x) {
  125. trouble = true;
  126. }
  127. }
  128. }
  129. private boolean closing = false; /* To avoid recursive closing */
  130. /**
  131. * Close the stream. This is done by flushing the stream and then closing
  132. * the underlying output stream.
  133. *
  134. * @see java.io.OutputStream#close()
  135. */
  136. public void close() {
  137. synchronized (this) {
  138. if (! closing) {
  139. closing = true;
  140. try {
  141. textOut.close();
  142. out.close();
  143. }
  144. catch (IOException x) {
  145. trouble = true;
  146. }
  147. textOut = null;
  148. charOut = null;
  149. out = null;
  150. }
  151. }
  152. }
  153. /**
  154. * Flush the stream and check its error state. The internal error state
  155. * is set to <code>true</code> when the underlying output stream throws an
  156. * <code>IOException</code> other than <code>InterruptedIOException</code>,
  157. * and when the <code>setError</code> method is invoked. If an operation
  158. * on the underlying output stream throws an
  159. * <code>InterruptedIOException</code>, then the <code>PrintStream</code>
  160. * converts the exception back into an interrupt by doing:
  161. * <pre>
  162. * Thread.currentThread().interrupt();
  163. * </pre>
  164. * or the equivalent.
  165. *
  166. * @return True if and only if this stream has encountered an
  167. * <code>IOException</code> other than
  168. * <code>InterruptedIOException</code>, or the
  169. * <code>setError</code> method has been invoked
  170. */
  171. public boolean checkError() {
  172. if (out != null)
  173. flush();
  174. return trouble;
  175. }
  176. /**
  177. * Set the error state of the stream to <code>true</code>.
  178. *
  179. * @since JDK1.1
  180. */
  181. protected void setError() {
  182. trouble = true;
  183. }
  184. /*
  185. * Exception-catching, synchronized output operations,
  186. * which also implement the write() methods of OutputStream
  187. */
  188. /**
  189. * Write the specified byte to this stream. If the byte is a newline and
  190. * automatic flushing is enabled then the <code>flush</code> method will be
  191. * invoked.
  192. *
  193. * <p> Note that the byte is written as given; to write a character that
  194. * will be translated according to the platform's default character
  195. * encoding, use the <code>print(char)</code> or <code>println(char)</code>
  196. * methods.
  197. *
  198. * @param b The byte to be written
  199. * @see #print(char)
  200. * @see #println(char)
  201. */
  202. public void write(int b) {
  203. try {
  204. synchronized (this) {
  205. ensureOpen();
  206. out.write(b);
  207. if ((b == '\n') && autoFlush)
  208. out.flush();
  209. }
  210. }
  211. catch (InterruptedIOException x) {
  212. Thread.currentThread().interrupt();
  213. }
  214. catch (IOException x) {
  215. trouble = true;
  216. }
  217. }
  218. /**
  219. * Write <code>len</code> bytes from the specified byte array starting at
  220. * offset <code>off</code> to this stream. If automatic flushing is
  221. * enabled then the <code>flush</code> method will be invoked.
  222. *
  223. * <p> Note that the bytes will be written as given; to write characters
  224. * that will be translated according to the platform's default character
  225. * encoding, use the <code>print(char)</code> or <code>println(char)</code>
  226. * methods.
  227. *
  228. * @param buf A byte array
  229. * @param off Offset from which to start taking bytes
  230. * @param len Number of bytes to write
  231. */
  232. public void write(byte buf[], int off, int len) {
  233. try {
  234. synchronized (this) {
  235. ensureOpen();
  236. out.write(buf, off, len);
  237. if (autoFlush)
  238. out.flush();
  239. }
  240. }
  241. catch (InterruptedIOException x) {
  242. Thread.currentThread().interrupt();
  243. }
  244. catch (IOException x) {
  245. trouble = true;
  246. }
  247. }
  248. /*
  249. * The following private methods on the text- and character-output streams
  250. * always flush the stream buffers, so that writes to the underlying byte
  251. * stream occur as promptly as with the original PrintStream.
  252. */
  253. private void write(char buf[]) {
  254. try {
  255. synchronized (this) {
  256. ensureOpen();
  257. textOut.write(buf);
  258. textOut.flushBuffer();
  259. charOut.flushBuffer();
  260. if (autoFlush) {
  261. for (int i = 0; i < buf.length; i++)
  262. if (buf[i] == '\n')
  263. out.flush();
  264. }
  265. }
  266. }
  267. catch (InterruptedIOException x) {
  268. Thread.currentThread().interrupt();
  269. }
  270. catch (IOException x) {
  271. trouble = true;
  272. }
  273. }
  274. private void write(String s) {
  275. try {
  276. synchronized (this) {
  277. ensureOpen();
  278. textOut.write(s);
  279. textOut.flushBuffer();
  280. charOut.flushBuffer();
  281. if (autoFlush && (s.indexOf('\n') >= 0))
  282. out.flush();
  283. }
  284. }
  285. catch (InterruptedIOException x) {
  286. Thread.currentThread().interrupt();
  287. }
  288. catch (IOException x) {
  289. trouble = true;
  290. }
  291. }
  292. private void newLine() {
  293. try {
  294. synchronized (this) {
  295. ensureOpen();
  296. textOut.newLine();
  297. textOut.flushBuffer();
  298. charOut.flushBuffer();
  299. if (autoFlush)
  300. out.flush();
  301. }
  302. }
  303. catch (InterruptedIOException x) {
  304. Thread.currentThread().interrupt();
  305. }
  306. catch (IOException x) {
  307. trouble = true;
  308. }
  309. }
  310. /* Methods that do not terminate lines */
  311. /**
  312. * Print a boolean value. The string produced by <code>{@link
  313. * java.lang.String#valueOf(boolean)}</code> is translated into bytes
  314. * according to the platform's default character encoding, and these bytes
  315. * are written in exactly the manner of the
  316. * <code>{@link #write(int)}</code> method.
  317. *
  318. * @param b The <code>boolean</code> to be printed
  319. */
  320. public void print(boolean b) {
  321. write(b ? "true" : "false");
  322. }
  323. /**
  324. * Print a character. The character is translated into one or more bytes
  325. * according to the platform's default character encoding, and these bytes
  326. * are written in exactly the manner of the
  327. * <code>{@link #write(int)}</code> method.
  328. *
  329. * @param c The <code>char</code> to be printed
  330. */
  331. public void print(char c) {
  332. write(String.valueOf(c));
  333. }
  334. /**
  335. * Print an integer. The string produced by <code>{@link
  336. * java.lang.String#valueOf(int)}</code> is translated into bytes
  337. * according to the platform's default character encoding, and these bytes
  338. * are written in exactly the manner of the
  339. * <code>{@link #write(int)}</code> method.
  340. *
  341. * @param i The <code>int</code> to be printed
  342. * @see java.lang.Integer#toString(int)
  343. */
  344. public void print(int i) {
  345. write(String.valueOf(i));
  346. }
  347. /**
  348. * Print a long integer. The string produced by <code>{@link
  349. * java.lang.String#valueOf(long)}</code> is translated into bytes
  350. * according to the platform's default character encoding, and these bytes
  351. * are written in exactly the manner of the
  352. * <code>{@link #write(int)}</code> method.
  353. *
  354. * @param l The <code>long</code> to be printed
  355. * @see java.lang.Long#toString(long)
  356. */
  357. public void print(long l) {
  358. write(String.valueOf(l));
  359. }
  360. /**
  361. * Print a floating-point number. The string produced by <code>{@link
  362. * java.lang.String#valueOf(float)}</code> is translated into bytes
  363. * according to the platform's default character encoding, and these bytes
  364. * are written in exactly the manner of the
  365. * <code>{@link #write(int)}</code> method.
  366. *
  367. * @param f The <code>float</code> to be printed
  368. * @see java.lang.Float#toString(float)
  369. */
  370. public void print(float f) {
  371. write(String.valueOf(f));
  372. }
  373. /**
  374. * Print a double-precision floating-point number. The string produced by
  375. * <code>{@link java.lang.String#valueOf(double)}</code> is translated into
  376. * bytes according to the platform's default character encoding, and these
  377. * bytes are written in exactly the manner of the <code>{@link
  378. * #write(int)}</code> method.
  379. *
  380. * @param d The <code>double</code> to be printed
  381. * @see java.lang.Double#toString(double)
  382. */
  383. public void print(double d) {
  384. write(String.valueOf(d));
  385. }
  386. /**
  387. * Print an array of characters. The characters are converted into bytes
  388. * according to the platform's default character encoding, and these bytes
  389. * are written in exactly the manner of the
  390. * <code>{@link #write(int)}</code> method.
  391. *
  392. * @param s The array of chars to be printed
  393. *
  394. * @throws NullPointerException If <code>s</code> is <code>null</code>
  395. */
  396. public void print(char s[]) {
  397. write(s);
  398. }
  399. /**
  400. * Print a string. If the argument is <code>null</code> then the string
  401. * <code>"null"</code> is printed. Otherwise, the string's characters are
  402. * converted into bytes according to the platform's default character
  403. * encoding, and these bytes are written in exactly the manner of the
  404. * <code>{@link #write(int)}</code> method.
  405. *
  406. * @param s The <code>String</code> to be printed
  407. */
  408. public void print(String s) {
  409. if (s == null) {
  410. s = "null";
  411. }
  412. write(s);
  413. }
  414. /**
  415. * Print an object. The string produced by the <code>{@link
  416. * java.lang.String#valueOf(Object)}</code> method is translated into bytes
  417. * according to the platform's default character encoding, and these bytes
  418. * are written in exactly the manner of the
  419. * <code>{@link #write(int)}</code> method.
  420. *
  421. * @param obj The <code>Object</code> to be printed
  422. * @see java.lang.Object#toString()
  423. */
  424. public void print(Object obj) {
  425. write(String.valueOf(obj));
  426. }
  427. /* Methods that do terminate lines */
  428. /**
  429. * Terminate the current line by writing the line separator string. The
  430. * line separator string is defined by the system property
  431. * <code>line.separator</code>, and is not necessarily a single newline
  432. * character (<code>'\n'</code>).
  433. */
  434. public void println() {
  435. newLine();
  436. }
  437. /**
  438. * Print a boolean and then terminate the line. This method behaves as
  439. * though it invokes <code>{@link #print(boolean)}</code> and then
  440. * <code>{@link #println()}</code>.
  441. *
  442. * @param x The <code>boolean</code> to be printed
  443. */
  444. public void println(boolean x) {
  445. synchronized (this) {
  446. print(x);
  447. newLine();
  448. }
  449. }
  450. /**
  451. * Print a character and then terminate the line. This method behaves as
  452. * though it invokes <code>{@link #print(char)}</code> and then
  453. * <code>{@link #println()}</code>.
  454. *
  455. * @param x The <code>char</code> to be printed.
  456. */
  457. public void println(char x) {
  458. synchronized (this) {
  459. print(x);
  460. newLine();
  461. }
  462. }
  463. /**
  464. * Print an integer and then terminate the line. This method behaves as
  465. * though it invokes <code>{@link #print(int)}</code> and then
  466. * <code>{@link #println()}</code>.
  467. *
  468. * @param x The <code>int</code> to be printed.
  469. */
  470. public void println(int x) {
  471. synchronized (this) {
  472. print(x);
  473. newLine();
  474. }
  475. }
  476. /**
  477. * Print a long and then terminate the line. This method behaves as
  478. * though it invokes <code>{@link #print(long)}</code> and then
  479. * <code>{@link #println()}</code>.
  480. *
  481. * @param x a The <code>long</code> to be printed.
  482. */
  483. public void println(long x) {
  484. synchronized (this) {
  485. print(x);
  486. newLine();
  487. }
  488. }
  489. /**
  490. * Print a float and then terminate the line. This method behaves as
  491. * though it invokes <code>{@link #print(float)}</code> and then
  492. * <code>{@link #println()}</code>.
  493. *
  494. * @param x The <code>float</code> to be printed.
  495. */
  496. public void println(float x) {
  497. synchronized (this) {
  498. print(x);
  499. newLine();
  500. }
  501. }
  502. /**
  503. * Print a double and then terminate the line. This method behaves as
  504. * though it invokes <code>{@link #print(double)}</code> and then
  505. * <code>{@link #println()}</code>.
  506. *
  507. * @param x The <code>double</code> to be printed.
  508. */
  509. public void println(double x) {
  510. synchronized (this) {
  511. print(x);
  512. newLine();
  513. }
  514. }
  515. /**
  516. * Print an array of characters and then terminate the line. This method
  517. * behaves as though it invokes <code>{@link #print(char[])}</code> and
  518. * then <code>{@link #println()}</code>.
  519. *
  520. * @param x an array of chars to print.
  521. */
  522. public void println(char x[]) {
  523. synchronized (this) {
  524. print(x);
  525. newLine();
  526. }
  527. }
  528. /**
  529. * Print a String and then terminate the line. This method behaves as
  530. * though it invokes <code>{@link #print(String)}</code> and then
  531. * <code>{@link #println()}</code>.
  532. *
  533. * @param x The <code>String</code> to be printed.
  534. */
  535. public void println(String x) {
  536. synchronized (this) {
  537. print(x);
  538. newLine();
  539. }
  540. }
  541. /**
  542. * Print an Object and then terminate the line. This method behaves as
  543. * though it invokes <code>{@link #print(Object)}</code> and then
  544. * <code>{@link #println()}</code>.
  545. *
  546. * @param x The <code>Object</code> to be printed.
  547. */
  548. public void println(Object x) {
  549. synchronized (this) {
  550. print(x);
  551. newLine();
  552. }
  553. }
  554. }