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