Print this page


Split Close
Expand all
Collapse all
          --- old/src/share/classes/java/io/PrintStream.java
          +++ new/src/share/classes/java/io/PrintStream.java
↓ open down ↓ 19 lines elided ↑ open up ↑
  20   20   *
  21   21   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22   22   * or visit www.oracle.com if you need additional information or have any
  23   23   * questions.
  24   24   */
  25   25  
  26   26  package java.io;
  27   27  
  28   28  import java.util.Formatter;
  29   29  import java.util.Locale;
       30 +import java.nio.charset.Charset;
       31 +import java.nio.charset.IllegalCharsetNameException;
  30   32  
  31      -
  32   33  /**
  33   34   * A <code>PrintStream</code> adds functionality to another output stream,
  34   35   * namely the ability to print representations of various data values
  35   36   * conveniently.  Two other features are provided as well.  Unlike other output
  36   37   * streams, a <code>PrintStream</code> never throws an
  37   38   * <code>IOException</code>; instead, exceptional situations merely set an
  38   39   * internal flag that can be tested via the <code>checkError</code> method.
  39   40   * Optionally, a <code>PrintStream</code> can be created so as to flush
  40   41   * automatically; this means that the <code>flush</code> method is
  41   42   * automatically invoked after a byte array is written, one of the
↓ open down ↓ 7 lines elided ↑ open up ↑
  49   50   *
  50   51   * @author     Frank Yellin
  51   52   * @author     Mark Reinhold
  52   53   * @since      JDK1.0
  53   54   */
  54   55  
  55   56  public class PrintStream extends FilterOutputStream
  56   57      implements Appendable, Closeable
  57   58  {
  58   59  
  59      -    private boolean autoFlush = false;
       60 +    private final boolean autoFlush;
  60   61      private boolean trouble = false;
  61   62      private Formatter formatter;
  62   63  
  63   64      /**
  64   65       * Track both the text- and character-output streams, so that their buffers
  65   66       * can be flushed without flushing the entire stream.
  66   67       */
  67   68      private BufferedWriter textOut;
  68   69      private OutputStreamWriter charOut;
  69   70  
  70   71      /**
       72 +     * nonNull is explicitly delcared here so as not to create an extra
       73 +     * dependency on java.util.Objects.nonNull. PrintStream is loaded
       74 +     * early during system initialization.
       75 +     */
       76 +    private static <T> T nonNull(T obj, String message) {
       77 +        if (obj == null)
       78 +            throw new NullPointerException(message);
       79 +        return obj;
       80 +    }
       81 +
       82 +    /**
       83 +     * Returns the given charset name if it is supported.
       84 +     * @throws NullPointerException          is csn is null
       85 +     * @throws UnsupportedEncodingException  if the charset is not supported
       86 +     */
       87 +    private static String verifyCharsetName(String csn)
       88 +            throws UnsupportedEncodingException {
       89 +        nonNull(csn, "charsetName");
       90 +        try {
       91 +            if (Charset.isSupported(csn))
       92 +                return csn;
       93 +        } catch (IllegalCharsetNameException unused) {
       94 +            /* swallow this exception since UnsupportedEncodingException
       95 +             * will be thrown */
       96 +        }
       97 +        throw new UnsupportedEncodingException(csn);
       98 +    }
       99 +
      100 +    /* Private constructors */
      101 +    private PrintStream(boolean autoFlush, OutputStream out) {
      102 +        super(out);
      103 +        this.autoFlush = autoFlush;
      104 +        this.charOut = new OutputStreamWriter(this);
      105 +        this.textOut = new BufferedWriter(charOut);
      106 +    }
      107 +    
      108 +    private PrintStream(boolean autoFlush, OutputStream out, String csn)
      109 +            throws UnsupportedEncodingException {
      110 +        super(out);
      111 +        this.autoFlush = autoFlush;
      112 +        this.charOut = new OutputStreamWriter(this, csn);
      113 +        this.textOut = new BufferedWriter(charOut);
      114 +    }
      115 +    
      116 +    /* Variant of the private constructor so that the given charset name
      117 +     * can be verified before evaluating the OutputStream argument. Used
      118 +     * by constructors creating a FileOutputStream that also take a
      119 +     * charset name.
      120 +     */
      121 +    private PrintStream(boolean autoFlush, String csn, OutputStream out)
      122 +            throws UnsupportedEncodingException {
      123 +        this(autoFlush, out, csn);
      124 +    }
      125 +
      126 +    /**
  71  127       * Creates a new print stream.  This stream will not flush automatically.
  72  128       *
  73  129       * @param  out        The output stream to which values and objects will be
  74  130       *                    printed
  75  131       *
  76  132       * @see java.io.PrintWriter#PrintWriter(java.io.OutputStream)
  77  133       */
  78  134      public PrintStream(OutputStream out) {
  79  135          this(out, false);
  80  136      }
  81  137  
  82      -    /* Initialization is factored into a private constructor (note the swapped
  83      -     * parameters so that this one isn't confused with the public one) and a
  84      -     * separate init method so that the following two public constructors can
  85      -     * share code.  We use a separate init method so that the constructor that
  86      -     * takes an encoding will throw an NPE for a null stream before it throws
  87      -     * an UnsupportedEncodingException for an unsupported encoding.
  88      -     */
  89      -
  90      -    private PrintStream(boolean autoFlush, OutputStream out)
  91      -    {
  92      -        super(out);
  93      -        if (out == null)
  94      -            throw new NullPointerException("Null output stream");
  95      -        this.autoFlush = autoFlush;
  96      -    }
  97      -
  98      -    private void init(OutputStreamWriter osw) {
  99      -        this.charOut = osw;
 100      -        this.textOut = new BufferedWriter(osw);
 101      -    }
 102      -
 103  138      /**
 104  139       * Creates a new print stream.
 105  140       *
 106  141       * @param  out        The output stream to which values and objects will be
 107  142       *                    printed
 108  143       * @param  autoFlush  A boolean; if true, the output buffer will be flushed
 109  144       *                    whenever a byte array is written, one of the
 110  145       *                    <code>println</code> methods is invoked, or a newline
 111  146       *                    character or byte (<code>'\n'</code>) is written
 112  147       *
 113  148       * @see java.io.PrintWriter#PrintWriter(java.io.OutputStream, boolean)
 114  149       */
 115  150      public PrintStream(OutputStream out, boolean autoFlush) {
 116      -        this(autoFlush, out);
 117      -        init(new OutputStreamWriter(this));
      151 +        this(autoFlush, nonNull(out, "Null output stream"));
 118  152      }
 119  153  
 120  154      /**
 121  155       * Creates a new print stream.
 122  156       *
 123  157       * @param  out        The output stream to which values and objects will be
 124  158       *                    printed
 125  159       * @param  autoFlush  A boolean; if true, the output buffer will be flushed
 126  160       *                    whenever a byte array is written, one of the
 127  161       *                    <code>println</code> methods is invoked, or a newline
↓ open down ↓ 3 lines elided ↑ open up ↑
 131  165       *                    character encoding</a>
 132  166       *
 133  167       * @throws  UnsupportedEncodingException
 134  168       *          If the named encoding is not supported
 135  169       *
 136  170       * @since  1.4
 137  171       */
 138  172      public PrintStream(OutputStream out, boolean autoFlush, String encoding)
 139  173          throws UnsupportedEncodingException
 140  174      {
 141      -        this(autoFlush, out);
 142      -        init(new OutputStreamWriter(this, encoding));
      175 +        /* this(boolean,OutputStream,String) is invoked so that the
      176 +         * OutputStream argument can be validated before the charset name.
      177 +         */
      178 +        this(autoFlush,
      179 +             nonNull(out, "Null output stream"),
      180 +             verifyCharsetName(encoding));
 143  181      }
 144  182  
 145  183      /**
 146  184       * Creates a new print stream, without automatic line flushing, with the
 147  185       * specified file name.  This convenience constructor creates
 148  186       * the necessary intermediate {@link java.io.OutputStreamWriter
 149  187       * OutputStreamWriter}, which will encode characters using the
 150  188       * {@linkplain java.nio.charset.Charset#defaultCharset() default charset}
 151  189       * for this instance of the Java virtual machine.
 152  190       *
↓ open down ↓ 11 lines elided ↑ open up ↑
 164  202       *
 165  203       * @throws  SecurityException
 166  204       *          If a security manager is present and {@link
 167  205       *          SecurityManager#checkWrite checkWrite(fileName)} denies write
 168  206       *          access to the file
 169  207       *
 170  208       * @since  1.5
 171  209       */
 172  210      public PrintStream(String fileName) throws FileNotFoundException {
 173  211          this(false, new FileOutputStream(fileName));
 174      -        init(new OutputStreamWriter(this));
 175  212      }
 176  213  
 177  214      /**
 178  215       * Creates a new print stream, without automatic line flushing, with the
 179  216       * specified file name and charset.  This convenience constructor creates
 180  217       * the necessary intermediate {@link java.io.OutputStreamWriter
 181  218       * OutputStreamWriter}, which will encode characters using the provided
 182  219       * charset.
 183  220       *
 184  221       * @param  fileName
↓ open down ↓ 18 lines elided ↑ open up ↑
 203  240       *          access to the file
 204  241       *
 205  242       * @throws  UnsupportedEncodingException
 206  243       *          If the named charset is not supported
 207  244       *
 208  245       * @since  1.5
 209  246       */
 210  247      public PrintStream(String fileName, String csn)
 211  248          throws FileNotFoundException, UnsupportedEncodingException
 212  249      {
 213      -        this(false, new FileOutputStream(fileName));
 214      -        init(new OutputStreamWriter(this, csn));
      250 +        /* this(boolean,String,OutputStream) is invoked so that the 
      251 +         * charset name can be verified before creating an output
      252 +         * stream to the file. */
      253 +        this(false, verifyCharsetName(csn), new FileOutputStream(fileName));
 215  254      }
 216  255  
 217  256      /**
 218  257       * Creates a new print stream, without automatic line flushing, with the
 219  258       * specified file.  This convenience constructor creates the necessary
 220  259       * intermediate {@link java.io.OutputStreamWriter OutputStreamWriter},
 221  260       * which will encode characters using the {@linkplain
 222  261       * java.nio.charset.Charset#defaultCharset() default charset} for this
 223  262       * instance of the Java virtual machine.
 224  263       *
↓ open down ↓ 11 lines elided ↑ open up ↑
 236  275       *
 237  276       * @throws  SecurityException
 238  277       *          If a security manager is present and {@link
 239  278       *          SecurityManager#checkWrite checkWrite(file.getPath())}
 240  279       *          denies write access to the file
 241  280       *
 242  281       * @since  1.5
 243  282       */
 244  283      public PrintStream(File file) throws FileNotFoundException {
 245  284          this(false, new FileOutputStream(file));
 246      -        init(new OutputStreamWriter(this));
 247  285      }
 248  286  
 249  287      /**
 250  288       * Creates a new print stream, without automatic line flushing, with the
 251  289       * specified file and charset.  This convenience constructor creates
 252  290       * the necessary intermediate {@link java.io.OutputStreamWriter
 253  291       * OutputStreamWriter}, which will encode characters using the provided
 254  292       * charset.
 255  293       *
 256  294       * @param  file
↓ open down ↓ 18 lines elided ↑ open up ↑
 275  313       *          denies write access to the file
 276  314       *
 277  315       * @throws  UnsupportedEncodingException
 278  316       *          If the named charset is not supported
 279  317       *
 280  318       * @since  1.5
 281  319       */
 282  320      public PrintStream(File file, String csn)
 283  321          throws FileNotFoundException, UnsupportedEncodingException
 284  322      {
 285      -        this(false, new FileOutputStream(file));
 286      -        init(new OutputStreamWriter(this, csn));
      323 +        /* this(boolean,String,OutputStream) is invoked so that the
      324 +         * charset name can be verified before creating an output
      325 +         * stream to the file. */
      326 +        this(false, verifyCharsetName(csn), new FileOutputStream(file));
 287  327      }
 288  328  
 289  329      /** Check to make sure that the stream has not been closed */
 290  330      private void ensureOpen() throws IOException {
 291  331          if (out == null)
 292  332              throw new IOException("Stream closed");
 293  333      }
 294  334  
 295  335      /**
 296  336       * Flushes the stream.  This is done by writing any buffered output bytes to
↓ open down ↓ 800 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX