1. /*
  2. * @(#)PrintWriter.java 1.29 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. * Print formatted representations of objects to a text-output stream. This
  10. * class implements all of the print methods found in PrintStream. It does not
  11. * contain methods for writing raw bytes, for which a program should use
  12. * unencoded byte streams.
  13. *
  14. * <p> Unlike the PrintStream class, if automatic flushing is enabled it will
  15. * be done only when one of the println() methods is invoked, rather than
  16. * whenever a newline character happens to be output. The println() methods
  17. * use the platform's own notion of line separator rather than the newline
  18. * character.
  19. *
  20. * <p> Methods in this class never throw I/O exceptions. The client may
  21. * inquire as to whether any errors have occurred by invoking checkError().
  22. *
  23. * @version 1.29, 01/23/03
  24. * @author Frank Yellin
  25. * @author Mark Reinhold
  26. * @since JDK1.1
  27. */
  28. public class PrintWriter extends Writer {
  29. /**
  30. * The underlying character-output stream of this
  31. * <code>PrintWriter</code>.
  32. *
  33. * @since 1.2
  34. */
  35. protected Writer out;
  36. private boolean autoFlush = false;
  37. private boolean trouble = false;
  38. /**
  39. * Line separator string. This is the value of the line.separator
  40. * property at the moment that the stream was created.
  41. */
  42. private String lineSeparator;
  43. /**
  44. * Create a new PrintWriter, without automatic line flushing.
  45. *
  46. * @param out A character-output stream
  47. */
  48. public PrintWriter (Writer out) {
  49. this(out, false);
  50. }
  51. /**
  52. * Create a new PrintWriter.
  53. *
  54. * @param out A character-output stream
  55. * @param autoFlush A boolean; if true, the println() methods will flush
  56. * the output buffer
  57. */
  58. public PrintWriter(Writer out,
  59. boolean autoFlush) {
  60. super(out);
  61. this.out = out;
  62. this.autoFlush = autoFlush;
  63. lineSeparator = (String) java.security.AccessController.doPrivileged(
  64. new sun.security.action.GetPropertyAction("line.separator"));
  65. }
  66. /**
  67. * Create a new PrintWriter, without automatic line flushing, from an
  68. * existing OutputStream. This convenience constructor creates the
  69. * necessary intermediate OutputStreamWriter, which will convert characters
  70. * into bytes using the default character encoding.
  71. *
  72. * @param out An output stream
  73. *
  74. * @see java.io.OutputStreamWriter#OutputStreamWriter(java.io.OutputStream)
  75. */
  76. public PrintWriter(OutputStream out) {
  77. this(out, false);
  78. }
  79. /**
  80. * Create a new PrintWriter from an existing OutputStream. This
  81. * convenience constructor creates the necessary intermediate
  82. * OutputStreamWriter, which will convert characters into bytes using the
  83. * default character encoding.
  84. *
  85. * @param out An output stream
  86. * @param autoFlush A boolean; if true, the println() methods will flush
  87. * the output buffer
  88. *
  89. * @see java.io.OutputStreamWriter#OutputStreamWriter(java.io.OutputStream)
  90. */
  91. public PrintWriter(OutputStream out, boolean autoFlush) {
  92. this(new BufferedWriter(new OutputStreamWriter(out)), autoFlush);
  93. }
  94. /** Check to make sure that the stream has not been closed */
  95. private void ensureOpen() throws IOException {
  96. if (out == null)
  97. throw new IOException("Stream closed");
  98. }
  99. /**
  100. * Flush the stream.
  101. * @see #checkError()
  102. */
  103. public void flush() {
  104. try {
  105. synchronized (lock) {
  106. ensureOpen();
  107. out.flush();
  108. }
  109. }
  110. catch (IOException x) {
  111. trouble = true;
  112. }
  113. }
  114. /**
  115. * Close the stream.
  116. * @see #checkError()
  117. */
  118. public void close() {
  119. try {
  120. synchronized (lock) {
  121. if (out == null)
  122. return;
  123. out.close();
  124. out = null;
  125. }
  126. }
  127. catch (IOException x) {
  128. trouble = true;
  129. }
  130. }
  131. /**
  132. * Flush the stream if it's not closed and check its error state.
  133. * Errors are cumulative; once the stream encounters an error, this
  134. * routine will return true on all successive calls.
  135. *
  136. * @return True if the print stream has encountered an error, either on the
  137. * underlying output stream or during a format conversion.
  138. */
  139. public boolean checkError() {
  140. if (out != null)
  141. flush();
  142. return trouble;
  143. }
  144. /** Indicate that an error has occurred. */
  145. protected void setError() {
  146. trouble = true;
  147. }
  148. /*
  149. * Exception-catching, synchronized output operations,
  150. * which also implement the write() methods of Writer
  151. */
  152. /**
  153. * Write a single character.
  154. * @param c int specifying a character to be written.
  155. */
  156. public void write(int c) {
  157. try {
  158. synchronized (lock) {
  159. ensureOpen();
  160. out.write(c);
  161. }
  162. }
  163. catch (InterruptedIOException x) {
  164. Thread.currentThread().interrupt();
  165. }
  166. catch (IOException x) {
  167. trouble = true;
  168. }
  169. }
  170. /**
  171. * Write a portion of an array of characters.
  172. * @param buf Array of characters
  173. * @param off Offset from which to start writing characters
  174. * @param len Number of characters to write
  175. */
  176. public void write(char buf[], int off, int len) {
  177. try {
  178. synchronized (lock) {
  179. ensureOpen();
  180. out.write(buf, off, len);
  181. }
  182. }
  183. catch (InterruptedIOException x) {
  184. Thread.currentThread().interrupt();
  185. }
  186. catch (IOException x) {
  187. trouble = true;
  188. }
  189. }
  190. /**
  191. * Write an array of characters. This method cannot be inherited from the
  192. * Writer class because it must suppress I/O exceptions.
  193. * @param buf Array of characters to be written
  194. */
  195. public void write(char buf[]) {
  196. write(buf, 0, buf.length);
  197. }
  198. /**
  199. * Write a portion of a string.
  200. * @param s A String
  201. * @param off Offset from which to start writing characters
  202. * @param len Number of characters to write
  203. */
  204. public void write(String s, int off, int len) {
  205. try {
  206. synchronized (lock) {
  207. ensureOpen();
  208. out.write(s, off, len);
  209. }
  210. }
  211. catch (InterruptedIOException x) {
  212. Thread.currentThread().interrupt();
  213. }
  214. catch (IOException x) {
  215. trouble = true;
  216. }
  217. }
  218. /**
  219. * Write a string. This method cannot be inherited from the Writer class
  220. * because it must suppress I/O exceptions.
  221. * @param s String to be written
  222. */
  223. public void write(String s) {
  224. write(s, 0, s.length());
  225. }
  226. private void newLine() {
  227. try {
  228. synchronized (lock) {
  229. ensureOpen();
  230. out.write(lineSeparator);
  231. if (autoFlush)
  232. out.flush();
  233. }
  234. }
  235. catch (InterruptedIOException x) {
  236. Thread.currentThread().interrupt();
  237. }
  238. catch (IOException x) {
  239. trouble = true;
  240. }
  241. }
  242. /* Methods that do not terminate lines */
  243. /**
  244. * Print a boolean value. The string produced by <code>{@link
  245. * java.lang.String#valueOf(boolean)}</code> is translated into bytes
  246. * according to the platform's default character encoding, and these bytes
  247. * are written in exactly the manner of the <code>{@link
  248. * #write(int)}</code> method.
  249. *
  250. * @param b The <code>boolean</code> to be printed
  251. */
  252. public void print(boolean b) {
  253. write(b ? "true" : "false");
  254. }
  255. /**
  256. * Print a character. The character is translated into one or more bytes
  257. * according to the platform's default character encoding, and these bytes
  258. * are written in exactly the manner of the <code>{@link
  259. * #write(int)}</code> method.
  260. *
  261. * @param c The <code>char</code> to be printed
  262. */
  263. public void print(char c) {
  264. write(c);
  265. }
  266. /**
  267. * Print an integer. The string produced by <code>{@link
  268. * java.lang.String#valueOf(int)}</code> is translated into bytes according
  269. * to the platform's default character encoding, and these bytes are
  270. * written in exactly the manner of the <code>{@link #write(int)}</code>
  271. * method.
  272. *
  273. * @param i The <code>int</code> to be printed
  274. * @see java.lang.Integer#toString(int)
  275. */
  276. public void print(int i) {
  277. write(String.valueOf(i));
  278. }
  279. /**
  280. * Print a long integer. The string produced by <code>{@link
  281. * java.lang.String#valueOf(long)}</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 <code>{@link #write(int)}</code>
  284. * method.
  285. *
  286. * @param l The <code>long</code> to be printed
  287. * @see java.lang.Long#toString(long)
  288. */
  289. public void print(long l) {
  290. write(String.valueOf(l));
  291. }
  292. /**
  293. * Print a floating-point number. The string produced by <code>{@link
  294. * java.lang.String#valueOf(float)}</code> is translated into bytes
  295. * according to the platform's default character encoding, and these bytes
  296. * are written in exactly the manner of the <code>{@link #write(int)}</code>
  297. * method.
  298. *
  299. * @param f The <code>float</code> to be printed
  300. * @see java.lang.Float#toString(float)
  301. */
  302. public void print(float f) {
  303. write(String.valueOf(f));
  304. }
  305. /**
  306. * Print a double-precision floating-point number. The string produced by
  307. * <code>{@link java.lang.String#valueOf(double)}</code> is translated into
  308. * bytes according to the platform's default character encoding, and these
  309. * bytes are written in exactly the manner of the <code>{@link
  310. * #write(int)}</code> method.
  311. *
  312. * @param d The <code>double</code> to be printed
  313. * @see java.lang.Double#toString(double)
  314. */
  315. public void print(double d) {
  316. write(String.valueOf(d));
  317. }
  318. /**
  319. * Print an array of characters. The characters are converted into bytes
  320. * according to the platform's default character encoding, and these bytes
  321. * are written in exactly the manner of the <code>{@link #write(int)}</code>
  322. * method.
  323. *
  324. * @param s The array of chars to be printed
  325. *
  326. * @throws NullPointerException If <code>s</code> is <code>null</code>
  327. */
  328. public void print(char s[]) {
  329. write(s);
  330. }
  331. /**
  332. * Print a string. If the argument is <code>null</code> then the string
  333. * <code>"null"</code> is printed. Otherwise, the string's characters are
  334. * converted into bytes according to the platform's default character
  335. * encoding, and these bytes are written in exactly the manner of the
  336. * <code>{@link #write(int)}</code> method.
  337. *
  338. * @param s The <code>String</code> to be printed
  339. */
  340. public void print(String s) {
  341. if (s == null) {
  342. s = "null";
  343. }
  344. write(s);
  345. }
  346. /**
  347. * Print an object. The string produced by the <code>{@link
  348. * java.lang.String#valueOf(Object)}</code> method is translated into bytes
  349. * according to the platform's default character encoding, and these bytes
  350. * are written in exactly the manner of the <code>{@link #write(int)}</code>
  351. * method.
  352. *
  353. * @param obj The <code>Object</code> to be printed
  354. * @see java.lang.Object#toString()
  355. */
  356. public void print(Object obj) {
  357. write(String.valueOf(obj));
  358. }
  359. /* Methods that do terminate lines */
  360. /**
  361. * Terminate the current line by writing the line separator string. The
  362. * line separator string is defined by the system property
  363. * <code>line.separator</code>, and is not necessarily a single newline
  364. * character (<code>'\n'</code>).
  365. */
  366. public void println() {
  367. newLine();
  368. }
  369. /**
  370. * Print a boolean value and then terminate the line. This method behaves
  371. * as though it invokes <code>{@link #print(boolean)}</code> and then
  372. * <code>{@link #println()}</code>.
  373. *
  374. * @param x the <code>boolean</code> value to be printed
  375. */
  376. public void println(boolean x) {
  377. synchronized (lock) {
  378. print(x);
  379. println();
  380. }
  381. }
  382. /**
  383. * Print a character and then terminate the line. This method behaves as
  384. * though it invokes <code>{@link #print(char)}</code> and then <code>{@link
  385. * #println()}</code>.
  386. *
  387. * @param x the <code>char</code> value to be printed
  388. */
  389. public void println(char x) {
  390. synchronized (lock) {
  391. print(x);
  392. println();
  393. }
  394. }
  395. /**
  396. * Print an integer and then terminate the line. This method behaves as
  397. * though it invokes <code>{@link #print(int)}</code> and then <code>{@link
  398. * #println()}</code>.
  399. *
  400. * @param x the <code>int</code> value to be printed
  401. */
  402. public void println(int x) {
  403. synchronized (lock) {
  404. print(x);
  405. println();
  406. }
  407. }
  408. /**
  409. * Print a long integer and then terminate the line. This method behaves
  410. * as though it invokes <code>{@link #print(long)}</code> and then
  411. * <code>{@link #println()}</code>.
  412. *
  413. * @param x the <code>long</code> value to be printed
  414. */
  415. public void println(long x) {
  416. synchronized (lock) {
  417. print(x);
  418. println();
  419. }
  420. }
  421. /**
  422. * Print a floating-point number and then terminate the line. This method
  423. * behaves as though it invokes <code>{@link #print(float)}</code> and then
  424. * <code>{@link #println()}</code>.
  425. *
  426. * @param x the <code>float</code> value to be printed
  427. */
  428. public void println(float x) {
  429. synchronized (lock) {
  430. print(x);
  431. println();
  432. }
  433. }
  434. /**
  435. * Print a double-precision floating-point number and then terminate the
  436. * line. This method behaves as though it invokes <code>{@link
  437. * #print(double)}</code> and then <code>{@link #println()}</code>.
  438. *
  439. * @param x the <code>double</code> value to be printed
  440. */
  441. public void println(double x) {
  442. synchronized (lock) {
  443. print(x);
  444. println();
  445. }
  446. }
  447. /**
  448. * Print an array of characters and then terminate the line. This method
  449. * behaves as though it invokes <code>{@link #print(char[])}</code> and then
  450. * <code>{@link #println()}</code>.
  451. *
  452. * @param x the array of <code>char</code> values to be printed
  453. */
  454. public void println(char x[]) {
  455. synchronized (lock) {
  456. print(x);
  457. println();
  458. }
  459. }
  460. /**
  461. * Print a String and then terminate the line. This method behaves as
  462. * though it invokes <code>{@link #print(String)}</code> and then
  463. * <code>{@link #println()}</code>.
  464. *
  465. * @param x the <code>String</code> value to be printed
  466. */
  467. public void println(String x) {
  468. synchronized (lock) {
  469. print(x);
  470. println();
  471. }
  472. }
  473. /**
  474. * Print an Object and then terminate the line. This method behaves as
  475. * though it invokes <code>{@link #print(Object)}</code> and then
  476. * <code>{@link #println()}</code>.
  477. *
  478. * @param x the <code>Object</code> value to be printed
  479. */
  480. public void println(Object x) {
  481. synchronized (lock) {
  482. print(x);
  483. println();
  484. }
  485. }
  486. }