src/share/classes/java/util/Formatter.java

Print this page




  33 import java.io.FileNotFoundException;
  34 import java.io.Flushable;
  35 import java.io.OutputStream;
  36 import java.io.OutputStreamWriter;
  37 import java.io.PrintStream;
  38 import java.io.UnsupportedEncodingException;
  39 import java.math.BigDecimal;
  40 import java.math.BigInteger;
  41 import java.math.MathContext;
  42 import java.math.RoundingMode;
  43 import java.nio.charset.Charset;
  44 import java.text.DateFormatSymbols;
  45 import java.text.DecimalFormat;
  46 import java.text.DecimalFormatSymbols;
  47 import java.text.NumberFormat;
  48 import java.util.Calendar;
  49 import java.util.Date;
  50 import java.util.Locale;
  51 import java.util.regex.Matcher;
  52 import java.util.regex.Pattern;


  53 
  54 import sun.misc.FpUtils;
  55 import sun.misc.DoubleConsts;
  56 import sun.misc.FormattedFloatingDecimal;
  57 
  58 /**
  59  * An interpreter for printf-style format strings.  This class provides support
  60  * for layout justification and alignment, common formats for numeric, string,
  61  * and date/time data, and locale-specific output.  Common Java types such as
  62  * {@code byte}, {@link java.math.BigDecimal BigDecimal}, and {@link Calendar}
  63  * are supported.  Limited formatting customization for arbitrary user types is
  64  * provided through the {@link Formattable} interface.
  65  *
  66  * <p> Formatters are not necessarily safe for multithreaded access.  Thread
  67  * safety is optional and is the responsibility of users of methods in this
  68  * class.
  69  *
  70  * <p> Formatted printing for the Java language is heavily inspired by C's
  71  * {@code printf}.  Although the format strings are similar to C, some
  72  * customizations have been made to accommodate the Java language and exploit


1821  * </pre></blockquote>
1822  *
1823  * <p> The maximum number of arguments is limited by the maximum dimension of a
1824  * Java array as defined by the <a
1825  * href="http://java.sun.com/docs/books/vmspec/">Java Virtual Machine
1826  * Specification</a>.  If the argument index is does not correspond to an
1827  * available argument, then a {@link MissingFormatArgumentException} is thrown.
1828  *
1829  * <p> If there are more arguments than format specifiers, the extra arguments
1830  * are ignored.
1831  *
1832  * <p> Unless otherwise specified, passing a {@code null} argument to any
1833  * method or constructor in this class will cause a {@link
1834  * NullPointerException} to be thrown.
1835  *
1836  * @author  Iris Clark
1837  * @since 1.5
1838  */
1839 public final class Formatter implements Closeable, Flushable {
1840     private Appendable a;
1841     private Locale l;
1842 
1843     private IOException lastException;
1844 
1845     private char zero = '0';
1846     private static double scaleUp;
1847 
1848     // 1 (sign) + 19 (max # sig digits) + 1 ('.') + 1 ('e') + 1 (sign)
1849     // + 3 (max # exp digits) + 4 (error) = 30
1850     private static final int MAX_FD_CHARS = 30;
1851 
1852     // Initialize internal data.
1853     private void init(Appendable a, Locale l) {





























1854         this.a = a;
1855         this.l = l;
1856         setZero();
1857     }
1858 
1859     /**
1860      * Constructs a new formatter.
1861      *
1862      * <p> The destination of the formatted output is a {@link StringBuilder}
1863      * which may be retrieved by invoking {@link #out out()} and whose
1864      * current content may be converted into a string by invoking {@link
1865      * #toString toString()}.  The locale used is the {@linkplain
1866      * Locale#getDefault() default locale} for this instance of the Java
1867      * virtual machine.
1868      */
1869     public Formatter() {
1870         init(new StringBuilder(), Locale.getDefault(Locale.Category.FORMAT));
1871     }
1872 
1873     /**
1874      * Constructs a new formatter with the specified destination.
1875      *
1876      * <p> The locale used is the {@linkplain Locale#getDefault() default
1877      * locale} for this instance of the Java virtual machine.
1878      *
1879      * @param  a
1880      *         Destination for the formatted output.  If {@code a} is
1881      *         {@code null} then a {@link StringBuilder} will be created.
1882      */
1883     public Formatter(Appendable a) {
1884         if (a == null)
1885             a = new StringBuilder();
1886         init(a, Locale.getDefault(Locale.Category.FORMAT));
1887     }
1888 
1889     /**
1890      * Constructs a new formatter with the specified locale.
1891      *
1892      * <p> The destination of the formatted output is a {@link StringBuilder}
1893      * which may be retrieved by invoking {@link #out out()} and whose current
1894      * content may be converted into a string by invoking {@link #toString
1895      * toString()}.
1896      *
1897      * @param  l
1898      *         The {@linkplain java.util.Locale locale} to apply during
1899      *         formatting.  If {@code l} is {@code null} then no localization
1900      *         is applied.
1901      */
1902     public Formatter(Locale l) {
1903         init(new StringBuilder(), l);
1904     }
1905 
1906     /**
1907      * Constructs a new formatter with the specified destination and locale.
1908      *
1909      * @param  a
1910      *         Destination for the formatted output.  If {@code a} is
1911      *         {@code null} then a {@link StringBuilder} will be created.
1912      *
1913      * @param  l
1914      *         The {@linkplain java.util.Locale locale} to apply during
1915      *         formatting.  If {@code l} is {@code null} then no localization
1916      *         is applied.
1917      */
1918     public Formatter(Appendable a, Locale l) {
1919         if (a == null)
1920             a = new StringBuilder();
1921         init(a, l);
1922     }
1923 
1924     /**
1925      * Constructs a new formatter with the specified file name.
1926      *
1927      * <p> The charset used is the {@linkplain
1928      * java.nio.charset.Charset#defaultCharset() default charset} for this
1929      * instance of the Java virtual machine.
1930      *
1931      * <p> The locale used is the {@linkplain Locale#getDefault() default
1932      * locale} for this instance of the Java virtual machine.
1933      *
1934      * @param  fileName
1935      *         The name of the file to use as the destination of this
1936      *         formatter.  If the file exists then it will be truncated to
1937      *         zero size; otherwise, a new file will be created.  The output
1938      *         will be written to the file and is buffered.
1939      *
1940      * @throws  SecurityException
1941      *          If a security manager is present and {@link
1942      *          SecurityManager#checkWrite checkWrite(fileName)} denies write
1943      *          access to the file
1944      *
1945      * @throws  FileNotFoundException
1946      *          If the given file name does not denote an existing, writable
1947      *          regular file and a new regular file of that name cannot be
1948      *          created, or if some other error occurs while opening or
1949      *          creating the file
1950      */
1951     public Formatter(String fileName) throws FileNotFoundException {
1952         init(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName))),
1953              Locale.getDefault(Locale.Category.FORMAT));
1954     }
1955 
1956     /**
1957      * Constructs a new formatter with the specified file name and charset.
1958      *
1959      * <p> The locale used is the {@linkplain Locale#getDefault default
1960      * locale} for this instance of the Java virtual machine.
1961      *
1962      * @param  fileName
1963      *         The name of the file to use as the destination of this
1964      *         formatter.  If the file exists then it will be truncated to
1965      *         zero size; otherwise, a new file will be created.  The output
1966      *         will be written to the file and is buffered.
1967      *
1968      * @param  csn
1969      *         The name of a supported {@linkplain java.nio.charset.Charset
1970      *         charset}
1971      *
1972      * @throws  FileNotFoundException
1973      *          If the given file name does not denote an existing, writable


2008      *         formatting.  If {@code l} is {@code null} then no localization
2009      *         is applied.
2010      *
2011      * @throws  FileNotFoundException
2012      *          If the given file name does not denote an existing, writable
2013      *          regular file and a new regular file of that name cannot be
2014      *          created, or if some other error occurs while opening or
2015      *          creating the file
2016      *
2017      * @throws  SecurityException
2018      *          If a security manager is present and {@link
2019      *          SecurityManager#checkWrite checkWrite(fileName)} denies write
2020      *          access to the file
2021      *
2022      * @throws  UnsupportedEncodingException
2023      *          If the named charset is not supported
2024      */
2025     public Formatter(String fileName, String csn, Locale l)
2026         throws FileNotFoundException, UnsupportedEncodingException
2027     {
2028         init(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName), csn)),
2029              l);

2030     }
2031 
2032     /**
2033      * Constructs a new formatter with the specified file.
2034      *
2035      * <p> The charset used is the {@linkplain
2036      * java.nio.charset.Charset#defaultCharset() default charset} for this
2037      * instance of the Java virtual machine.
2038      *
2039      * <p> The locale used is the {@linkplain Locale#getDefault() default
2040      * locale} for this instance of the Java virtual machine.
2041      *
2042      * @param  file
2043      *         The file to use as the destination of this formatter.  If the
2044      *         file exists then it will be truncated to zero size; otherwise,
2045      *         a new file will be created.  The output will be written to the
2046      *         file and is buffered.
2047      *
2048      * @throws  SecurityException
2049      *          If a security manager is present and {@link
2050      *          SecurityManager#checkWrite checkWrite(file.getPath())} denies
2051      *          write access to the file
2052      *
2053      * @throws  FileNotFoundException
2054      *          If the given file object does not denote an existing, writable
2055      *          regular file and a new regular file of that name cannot be
2056      *          created, or if some other error occurs while opening or
2057      *          creating the file
2058      */
2059     public Formatter(File file) throws FileNotFoundException {
2060         init(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file))),
2061              Locale.getDefault(Locale.Category.FORMAT));
2062     }
2063 
2064     /**
2065      * Constructs a new formatter with the specified file and charset.
2066      *
2067      * <p> The locale used is the {@linkplain Locale#getDefault default
2068      * locale} for this instance of the Java virtual machine.
2069      *
2070      * @param  file
2071      *         The file to use as the destination of this formatter.  If the
2072      *         file exists then it will be truncated to zero size; otherwise,
2073      *         a new file will be created.  The output will be written to the
2074      *         file and is buffered.
2075      *
2076      * @param  csn
2077      *         The name of a supported {@linkplain java.nio.charset.Charset
2078      *         charset}
2079      *
2080      * @throws  FileNotFoundException
2081      *          If the given file object does not denote an existing, writable


2116      *         formatting.  If {@code l} is {@code null} then no localization
2117      *         is applied.
2118      *
2119      * @throws  FileNotFoundException
2120      *          If the given file object does not denote an existing, writable
2121      *          regular file and a new regular file of that name cannot be
2122      *          created, or if some other error occurs while opening or
2123      *          creating the file
2124      *
2125      * @throws  SecurityException
2126      *          If a security manager is present and {@link
2127      *          SecurityManager#checkWrite checkWrite(file.getPath())} denies
2128      *          write access to the file
2129      *
2130      * @throws  UnsupportedEncodingException
2131      *          If the named charset is not supported
2132      */
2133     public Formatter(File file, String csn, Locale l)
2134         throws FileNotFoundException, UnsupportedEncodingException
2135     {
2136         init(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), csn)),
2137              l);

2138     }
2139 
2140     /**
2141      * Constructs a new formatter with the specified print stream.
2142      *
2143      * <p> The locale used is the {@linkplain Locale#getDefault() default
2144      * locale} for this instance of the Java virtual machine.
2145      *
2146      * <p> Characters are written to the given {@link java.io.PrintStream
2147      * PrintStream} object and are therefore encoded using that object's
2148      * charset.
2149      *
2150      * @param  ps
2151      *         The stream to use as the destination of this formatter.
2152      */
2153     public Formatter(PrintStream ps) {
2154         if (ps == null)
2155             throw new NullPointerException();
2156         init((Appendable)ps, Locale.getDefault(Locale.Category.FORMAT));
2157     }
2158 
2159     /**
2160      * Constructs a new formatter with the specified output stream.
2161      *
2162      * <p> The charset used is the {@linkplain
2163      * java.nio.charset.Charset#defaultCharset() default charset} for this
2164      * instance of the Java virtual machine.
2165      *
2166      * <p> The locale used is the {@linkplain Locale#getDefault() default
2167      * locale} for this instance of the Java virtual machine.
2168      *
2169      * @param  os
2170      *         The output stream to use as the destination of this formatter.
2171      *         The output will be buffered.
2172      */
2173     public Formatter(OutputStream os) {
2174         init(new BufferedWriter(new OutputStreamWriter(os)),
2175              Locale.getDefault(Locale.Category.FORMAT));
2176     }
2177 
2178     /**
2179      * Constructs a new formatter with the specified output stream and
2180      * charset.
2181      *
2182      * <p> The locale used is the {@linkplain Locale#getDefault default
2183      * locale} for this instance of the Java virtual machine.
2184      *
2185      * @param  os
2186      *         The output stream to use as the destination of this formatter.
2187      *         The output will be buffered.
2188      *
2189      * @param  csn
2190      *         The name of a supported {@linkplain java.nio.charset.Charset
2191      *         charset}
2192      *
2193      * @throws  UnsupportedEncodingException
2194      *          If the named charset is not supported
2195      */


2205      *
2206      * @param  os
2207      *         The output stream to use as the destination of this formatter.
2208      *         The output will be buffered.
2209      *
2210      * @param  csn
2211      *         The name of a supported {@linkplain java.nio.charset.Charset
2212      *         charset}
2213      *
2214      * @param  l
2215      *         The {@linkplain java.util.Locale locale} to apply during
2216      *         formatting.  If {@code l} is {@code null} then no localization
2217      *         is applied.
2218      *
2219      * @throws  UnsupportedEncodingException
2220      *          If the named charset is not supported
2221      */
2222     public Formatter(OutputStream os, String csn, Locale l)
2223         throws UnsupportedEncodingException
2224     {
2225         init(new BufferedWriter(new OutputStreamWriter(os, csn)), l);
2226     }
2227 
2228     private void setZero() {
2229         if ((l != null) && !l.equals(Locale.US)) {
2230             DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(l);
2231             zero = dfs.getZeroDigit();


2232         }
2233     }
2234 
2235     /**
2236      * Returns the locale set by the construction of this formatter.
2237      *
2238      * <p> The {@link #format(java.util.Locale,String,Object...) format} method
2239      * for this object which has a locale argument does not change this value.
2240      *
2241      * @return  {@code null} if no localization is applied, otherwise a
2242      *          locale
2243      *
2244      * @throws  FormatterClosedException
2245      *          If this formatter has been closed by invoking its {@link
2246      *          #close()} method
2247      */
2248     public Locale locale() {
2249         ensureOpen();
2250         return l;
2251     }




  33 import java.io.FileNotFoundException;
  34 import java.io.Flushable;
  35 import java.io.OutputStream;
  36 import java.io.OutputStreamWriter;
  37 import java.io.PrintStream;
  38 import java.io.UnsupportedEncodingException;
  39 import java.math.BigDecimal;
  40 import java.math.BigInteger;
  41 import java.math.MathContext;
  42 import java.math.RoundingMode;
  43 import java.nio.charset.Charset;
  44 import java.text.DateFormatSymbols;
  45 import java.text.DecimalFormat;
  46 import java.text.DecimalFormatSymbols;
  47 import java.text.NumberFormat;
  48 import java.util.Calendar;
  49 import java.util.Date;
  50 import java.util.Locale;
  51 import java.util.regex.Matcher;
  52 import java.util.regex.Pattern;
  53 import java.nio.charset.Charset;
  54 import java.nio.charset.IllegalCharsetNameException;
  55 
  56 import sun.misc.FpUtils;
  57 import sun.misc.DoubleConsts;
  58 import sun.misc.FormattedFloatingDecimal;
  59 
  60 /**
  61  * An interpreter for printf-style format strings.  This class provides support
  62  * for layout justification and alignment, common formats for numeric, string,
  63  * and date/time data, and locale-specific output.  Common Java types such as
  64  * {@code byte}, {@link java.math.BigDecimal BigDecimal}, and {@link Calendar}
  65  * are supported.  Limited formatting customization for arbitrary user types is
  66  * provided through the {@link Formattable} interface.
  67  *
  68  * <p> Formatters are not necessarily safe for multithreaded access.  Thread
  69  * safety is optional and is the responsibility of users of methods in this
  70  * class.
  71  *
  72  * <p> Formatted printing for the Java language is heavily inspired by C's
  73  * {@code printf}.  Although the format strings are similar to C, some
  74  * customizations have been made to accommodate the Java language and exploit


1823  * </pre></blockquote>
1824  *
1825  * <p> The maximum number of arguments is limited by the maximum dimension of a
1826  * Java array as defined by the <a
1827  * href="http://java.sun.com/docs/books/vmspec/">Java Virtual Machine
1828  * Specification</a>.  If the argument index is does not correspond to an
1829  * available argument, then a {@link MissingFormatArgumentException} is thrown.
1830  *
1831  * <p> If there are more arguments than format specifiers, the extra arguments
1832  * are ignored.
1833  *
1834  * <p> Unless otherwise specified, passing a {@code null} argument to any
1835  * method or constructor in this class will cause a {@link
1836  * NullPointerException} to be thrown.
1837  *
1838  * @author  Iris Clark
1839  * @since 1.5
1840  */
1841 public final class Formatter implements Closeable, Flushable {
1842     private Appendable a;
1843     private final Locale l;
1844 
1845     private IOException lastException;
1846 
1847     private final char zero;
1848     private static double scaleUp;
1849 
1850     // 1 (sign) + 19 (max # sig digits) + 1 ('.') + 1 ('e') + 1 (sign)
1851     // + 3 (max # exp digits) + 4 (error) = 30
1852     private static final int MAX_FD_CHARS = 30;
1853 
1854     /**
1855      * Verifies that the given charset is supported.
1856      * @throws NullPointerException          is csn is null
1857      * @throws UnsupportedEncodingException  if the charset is not supported
1858      */
1859     private static Void verifyCharsetName(String csn)
1860             throws UnsupportedEncodingException {
1861         Objects.nonNull(csn, "charsetName");
1862         try {
1863             if (Charset.isSupported(csn))
1864                 return null;
1865         } catch (IllegalCharsetNameException unused) {
1866             /* swallow this exception since UnsupportedEncodingException
1867              * will be thrown */
1868         }
1869         throw new UnsupportedEncodingException(csn);
1870     }
1871 
1872     private static final Appendable nonNullAppendable(Appendable a) {
1873         if (a == null)
1874             return new StringBuilder();
1875 
1876         return a;
1877     }
1878 
1879     // Private constructors
1880     private Formatter(Void unused, Locale l, Appendable a) {
1881         this(l, a);
1882     }
1883 
1884     private Formatter(Locale l, Appendable a) {
1885         this.a = a;
1886         this.l = l;
1887         this.zero = getZero(l);
1888     }
1889 
1890     /**
1891      * Constructs a new formatter.
1892      *
1893      * <p> The destination of the formatted output is a {@link StringBuilder}
1894      * which may be retrieved by invoking {@link #out out()} and whose
1895      * current content may be converted into a string by invoking {@link
1896      * #toString toString()}.  The locale used is the {@linkplain
1897      * Locale#getDefault() default locale} for this instance of the Java
1898      * virtual machine.
1899      */
1900     public Formatter() {
1901         this(Locale.getDefault(Locale.Category.FORMAT), new StringBuilder());
1902     }
1903 
1904     /**
1905      * Constructs a new formatter with the specified destination.
1906      *
1907      * <p> The locale used is the {@linkplain Locale#getDefault() default
1908      * locale} for this instance of the Java virtual machine.
1909      *
1910      * @param  a
1911      *         Destination for the formatted output.  If {@code a} is
1912      *         {@code null} then a {@link StringBuilder} will be created.
1913      */
1914     public Formatter(Appendable a) {
1915         this(Locale.getDefault(Locale.Category.FORMAT), nonNullAppendable(a));


1916     }
1917 
1918     /**
1919      * Constructs a new formatter with the specified locale.
1920      *
1921      * <p> The destination of the formatted output is a {@link StringBuilder}
1922      * which may be retrieved by invoking {@link #out out()} and whose current
1923      * content may be converted into a string by invoking {@link #toString
1924      * toString()}.
1925      *
1926      * @param  l
1927      *         The {@linkplain java.util.Locale locale} to apply during
1928      *         formatting.  If {@code l} is {@code null} then no localization
1929      *         is applied.
1930      */
1931     public Formatter(Locale l) {
1932         this(l, new StringBuilder());
1933     }
1934 
1935     /**
1936      * Constructs a new formatter with the specified destination and locale.
1937      *
1938      * @param  a
1939      *         Destination for the formatted output.  If {@code a} is
1940      *         {@code null} then a {@link StringBuilder} will be created.
1941      *
1942      * @param  l
1943      *         The {@linkplain java.util.Locale locale} to apply during
1944      *         formatting.  If {@code l} is {@code null} then no localization
1945      *         is applied.
1946      */
1947     public Formatter(Appendable a, Locale l) {
1948         this(l, nonNullAppendable(a));


1949     }
1950 
1951     /**
1952      * Constructs a new formatter with the specified file name.
1953      *
1954      * <p> The charset used is the {@linkplain
1955      * java.nio.charset.Charset#defaultCharset() default charset} for this
1956      * instance of the Java virtual machine.
1957      *
1958      * <p> The locale used is the {@linkplain Locale#getDefault() default
1959      * locale} for this instance of the Java virtual machine.
1960      *
1961      * @param  fileName
1962      *         The name of the file to use as the destination of this
1963      *         formatter.  If the file exists then it will be truncated to
1964      *         zero size; otherwise, a new file will be created.  The output
1965      *         will be written to the file and is buffered.
1966      *
1967      * @throws  SecurityException
1968      *          If a security manager is present and {@link
1969      *          SecurityManager#checkWrite checkWrite(fileName)} denies write
1970      *          access to the file
1971      *
1972      * @throws  FileNotFoundException
1973      *          If the given file name does not denote an existing, writable
1974      *          regular file and a new regular file of that name cannot be
1975      *          created, or if some other error occurs while opening or
1976      *          creating the file
1977      */
1978     public Formatter(String fileName) throws FileNotFoundException {
1979         this(Locale.getDefault(Locale.Category.FORMAT),
1980              new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName))));
1981     }
1982 
1983     /**
1984      * Constructs a new formatter with the specified file name and charset.
1985      *
1986      * <p> The locale used is the {@linkplain Locale#getDefault default
1987      * locale} for this instance of the Java virtual machine.
1988      *
1989      * @param  fileName
1990      *         The name of the file to use as the destination of this
1991      *         formatter.  If the file exists then it will be truncated to
1992      *         zero size; otherwise, a new file will be created.  The output
1993      *         will be written to the file and is buffered.
1994      *
1995      * @param  csn
1996      *         The name of a supported {@linkplain java.nio.charset.Charset
1997      *         charset}
1998      *
1999      * @throws  FileNotFoundException
2000      *          If the given file name does not denote an existing, writable


2035      *         formatting.  If {@code l} is {@code null} then no localization
2036      *         is applied.
2037      *
2038      * @throws  FileNotFoundException
2039      *          If the given file name does not denote an existing, writable
2040      *          regular file and a new regular file of that name cannot be
2041      *          created, or if some other error occurs while opening or
2042      *          creating the file
2043      *
2044      * @throws  SecurityException
2045      *          If a security manager is present and {@link
2046      *          SecurityManager#checkWrite checkWrite(fileName)} denies write
2047      *          access to the file
2048      *
2049      * @throws  UnsupportedEncodingException
2050      *          If the named charset is not supported
2051      */
2052     public Formatter(String fileName, String csn, Locale l)
2053         throws FileNotFoundException, UnsupportedEncodingException
2054     {
2055         this(verifyCharsetName(csn),
2056              l,
2057              new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName), csn)));
2058     }
2059 
2060     /**
2061      * Constructs a new formatter with the specified file.
2062      *
2063      * <p> The charset used is the {@linkplain
2064      * java.nio.charset.Charset#defaultCharset() default charset} for this
2065      * instance of the Java virtual machine.
2066      *
2067      * <p> The locale used is the {@linkplain Locale#getDefault() default
2068      * locale} for this instance of the Java virtual machine.
2069      *
2070      * @param  file
2071      *         The file to use as the destination of this formatter.  If the
2072      *         file exists then it will be truncated to zero size; otherwise,
2073      *         a new file will be created.  The output will be written to the
2074      *         file and is buffered.
2075      *
2076      * @throws  SecurityException
2077      *          If a security manager is present and {@link
2078      *          SecurityManager#checkWrite checkWrite(file.getPath())} denies
2079      *          write access to the file
2080      *
2081      * @throws  FileNotFoundException
2082      *          If the given file object does not denote an existing, writable
2083      *          regular file and a new regular file of that name cannot be
2084      *          created, or if some other error occurs while opening or
2085      *          creating the file
2086      */
2087     public Formatter(File file) throws FileNotFoundException {
2088         this(Locale.getDefault(Locale.Category.FORMAT),
2089              new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file))));
2090     }
2091 
2092     /**
2093      * Constructs a new formatter with the specified file and charset.
2094      *
2095      * <p> The locale used is the {@linkplain Locale#getDefault default
2096      * locale} for this instance of the Java virtual machine.
2097      *
2098      * @param  file
2099      *         The file to use as the destination of this formatter.  If the
2100      *         file exists then it will be truncated to zero size; otherwise,
2101      *         a new file will be created.  The output will be written to the
2102      *         file and is buffered.
2103      *
2104      * @param  csn
2105      *         The name of a supported {@linkplain java.nio.charset.Charset
2106      *         charset}
2107      *
2108      * @throws  FileNotFoundException
2109      *          If the given file object does not denote an existing, writable


2144      *         formatting.  If {@code l} is {@code null} then no localization
2145      *         is applied.
2146      *
2147      * @throws  FileNotFoundException
2148      *          If the given file object does not denote an existing, writable
2149      *          regular file and a new regular file of that name cannot be
2150      *          created, or if some other error occurs while opening or
2151      *          creating the file
2152      *
2153      * @throws  SecurityException
2154      *          If a security manager is present and {@link
2155      *          SecurityManager#checkWrite checkWrite(file.getPath())} denies
2156      *          write access to the file
2157      *
2158      * @throws  UnsupportedEncodingException
2159      *          If the named charset is not supported
2160      */
2161     public Formatter(File file, String csn, Locale l)
2162         throws FileNotFoundException, UnsupportedEncodingException
2163     {
2164         this(verifyCharsetName(csn),
2165              l,
2166              new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), csn)));
2167     }
2168 
2169     /**
2170      * Constructs a new formatter with the specified print stream.
2171      *
2172      * <p> The locale used is the {@linkplain Locale#getDefault() default
2173      * locale} for this instance of the Java virtual machine.
2174      *
2175      * <p> Characters are written to the given {@link java.io.PrintStream
2176      * PrintStream} object and are therefore encoded using that object's
2177      * charset.
2178      *
2179      * @param  ps
2180      *         The stream to use as the destination of this formatter.
2181      */
2182     public Formatter(PrintStream ps) {
2183         this(Locale.getDefault(Locale.Category.FORMAT),
2184              (Appendable)Objects.nonNull(ps));

2185     }
2186 
2187     /**
2188      * Constructs a new formatter with the specified output stream.
2189      *
2190      * <p> The charset used is the {@linkplain
2191      * java.nio.charset.Charset#defaultCharset() default charset} for this
2192      * instance of the Java virtual machine.
2193      *
2194      * <p> The locale used is the {@linkplain Locale#getDefault() default
2195      * locale} for this instance of the Java virtual machine.
2196      *
2197      * @param  os
2198      *         The output stream to use as the destination of this formatter.
2199      *         The output will be buffered.
2200      */
2201     public Formatter(OutputStream os) {
2202         this(Locale.getDefault(Locale.Category.FORMAT),
2203              new BufferedWriter(new OutputStreamWriter(os)));
2204     }
2205 
2206     /**
2207      * Constructs a new formatter with the specified output stream and
2208      * charset.
2209      *
2210      * <p> The locale used is the {@linkplain Locale#getDefault default
2211      * locale} for this instance of the Java virtual machine.
2212      *
2213      * @param  os
2214      *         The output stream to use as the destination of this formatter.
2215      *         The output will be buffered.
2216      *
2217      * @param  csn
2218      *         The name of a supported {@linkplain java.nio.charset.Charset
2219      *         charset}
2220      *
2221      * @throws  UnsupportedEncodingException
2222      *          If the named charset is not supported
2223      */


2233      *
2234      * @param  os
2235      *         The output stream to use as the destination of this formatter.
2236      *         The output will be buffered.
2237      *
2238      * @param  csn
2239      *         The name of a supported {@linkplain java.nio.charset.Charset
2240      *         charset}
2241      *
2242      * @param  l
2243      *         The {@linkplain java.util.Locale locale} to apply during
2244      *         formatting.  If {@code l} is {@code null} then no localization
2245      *         is applied.
2246      *
2247      * @throws  UnsupportedEncodingException
2248      *          If the named charset is not supported
2249      */
2250     public Formatter(OutputStream os, String csn, Locale l)
2251         throws UnsupportedEncodingException
2252     {
2253         this(l, new BufferedWriter(new OutputStreamWriter(os, csn)));
2254     }
2255 
2256     private static final char getZero(Locale l) {
2257         if ((l != null) && !l.equals(Locale.US)) {
2258             DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(l);
2259             return dfs.getZeroDigit();
2260         } else {
2261             return '0';
2262         }
2263     }
2264 
2265     /**
2266      * Returns the locale set by the construction of this formatter.
2267      *
2268      * <p> The {@link #format(java.util.Locale,String,Object...) format} method
2269      * for this object which has a locale argument does not change this value.
2270      *
2271      * @return  {@code null} if no localization is applied, otherwise a
2272      *          locale
2273      *
2274      * @throws  FormatterClosedException
2275      *          If this formatter has been closed by invoking its {@link
2276      *          #close()} method
2277      */
2278     public Locale locale() {
2279         ensureOpen();
2280         return l;
2281     }