Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/java/io/BufferedWriter.java
38829 views
/*1* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package java.io;262728/**29* Writes text to a character-output stream, buffering characters so as to30* provide for the efficient writing of single characters, arrays, and strings.31*32* <p> The buffer size may be specified, or the default size may be accepted.33* The default is large enough for most purposes.34*35* <p> A newLine() method is provided, which uses the platform's own notion of36* line separator as defined by the system property <tt>line.separator</tt>.37* Not all platforms use the newline character ('\n') to terminate lines.38* Calling this method to terminate each output line is therefore preferred to39* writing a newline character directly.40*41* <p> In general, a Writer sends its output immediately to the underlying42* character or byte stream. Unless prompt output is required, it is advisable43* to wrap a BufferedWriter around any Writer whose write() operations may be44* costly, such as FileWriters and OutputStreamWriters. For example,45*46* <pre>47* PrintWriter out48* = new PrintWriter(new BufferedWriter(new FileWriter("foo.out")));49* </pre>50*51* will buffer the PrintWriter's output to the file. Without buffering, each52* invocation of a print() method would cause characters to be converted into53* bytes that would then be written immediately to the file, which can be very54* inefficient.55*56* @see PrintWriter57* @see FileWriter58* @see OutputStreamWriter59* @see java.nio.file.Files#newBufferedWriter60*61* @author Mark Reinhold62* @since JDK1.163*/6465public class BufferedWriter extends Writer {6667private Writer out;6869private char cb[];70private int nChars, nextChar;7172private static int defaultCharBufferSize = 8192;7374/**75* Line separator string. This is the value of the line.separator76* property at the moment that the stream was created.77*/78private String lineSeparator;7980/**81* Creates a buffered character-output stream that uses a default-sized82* output buffer.83*84* @param out A Writer85*/86public BufferedWriter(Writer out) {87this(out, defaultCharBufferSize);88}8990/**91* Creates a new buffered character-output stream that uses an output92* buffer of the given size.93*94* @param out A Writer95* @param sz Output-buffer size, a positive integer96*97* @exception IllegalArgumentException If {@code sz <= 0}98*/99public BufferedWriter(Writer out, int sz) {100super(out);101if (sz <= 0)102throw new IllegalArgumentException("Buffer size <= 0");103this.out = out;104cb = new char[sz];105nChars = sz;106nextChar = 0;107108lineSeparator = java.security.AccessController.doPrivileged(109new sun.security.action.GetPropertyAction("line.separator"));110}111112/** Checks to make sure that the stream has not been closed */113private void ensureOpen() throws IOException {114if (out == null)115throw new IOException("Stream closed");116}117118/**119* Flushes the output buffer to the underlying character stream, without120* flushing the stream itself. This method is non-private only so that it121* may be invoked by PrintStream.122*/123void flushBuffer() throws IOException {124synchronized (lock) {125ensureOpen();126if (nextChar == 0)127return;128out.write(cb, 0, nextChar);129nextChar = 0;130}131}132133/**134* Writes a single character.135*136* @exception IOException If an I/O error occurs137*/138public void write(int c) throws IOException {139synchronized (lock) {140ensureOpen();141if (nextChar >= nChars)142flushBuffer();143cb[nextChar++] = (char) c;144}145}146147/**148* Our own little min method, to avoid loading java.lang.Math if we've run149* out of file descriptors and we're trying to print a stack trace.150*/151private int min(int a, int b) {152if (a < b) return a;153return b;154}155156/**157* Writes a portion of an array of characters.158*159* <p> Ordinarily this method stores characters from the given array into160* this stream's buffer, flushing the buffer to the underlying stream as161* needed. If the requested length is at least as large as the buffer,162* however, then this method will flush the buffer and write the characters163* directly to the underlying stream. Thus redundant164* <code>BufferedWriter</code>s will not copy data unnecessarily.165*166* @param cbuf A character array167* @param off Offset from which to start reading characters168* @param len Number of characters to write169*170* @exception IOException If an I/O error occurs171*/172public void write(char cbuf[], int off, int len) throws IOException {173synchronized (lock) {174ensureOpen();175if ((off < 0) || (off > cbuf.length) || (len < 0) ||176((off + len) > cbuf.length) || ((off + len) < 0)) {177throw new IndexOutOfBoundsException();178} else if (len == 0) {179return;180}181182if (len >= nChars) {183/* If the request length exceeds the size of the output buffer,184flush the buffer and then write the data directly. In this185way buffered streams will cascade harmlessly. */186flushBuffer();187out.write(cbuf, off, len);188return;189}190191int b = off, t = off + len;192while (b < t) {193int d = min(nChars - nextChar, t - b);194System.arraycopy(cbuf, b, cb, nextChar, d);195b += d;196nextChar += d;197if (nextChar >= nChars)198flushBuffer();199}200}201}202203/**204* Writes a portion of a String.205*206* <p> If the value of the <tt>len</tt> parameter is negative then no207* characters are written. This is contrary to the specification of this208* method in the {@linkplain java.io.Writer#write(java.lang.String,int,int)209* superclass}, which requires that an {@link IndexOutOfBoundsException} be210* thrown.211*212* @param s String to be written213* @param off Offset from which to start reading characters214* @param len Number of characters to be written215*216* @exception IOException If an I/O error occurs217*/218public void write(String s, int off, int len) throws IOException {219synchronized (lock) {220ensureOpen();221222int b = off, t = off + len;223while (b < t) {224int d = min(nChars - nextChar, t - b);225s.getChars(b, b + d, cb, nextChar);226b += d;227nextChar += d;228if (nextChar >= nChars)229flushBuffer();230}231}232}233234/**235* Writes a line separator. The line separator string is defined by the236* system property <tt>line.separator</tt>, and is not necessarily a single237* newline ('\n') character.238*239* @exception IOException If an I/O error occurs240*/241public void newLine() throws IOException {242write(lineSeparator);243}244245/**246* Flushes the stream.247*248* @exception IOException If an I/O error occurs249*/250public void flush() throws IOException {251synchronized (lock) {252flushBuffer();253out.flush();254}255}256257@SuppressWarnings("try")258public void close() throws IOException {259synchronized (lock) {260if (out == null) {261return;262}263try (Writer w = out) {264flushBuffer();265} finally {266out = null;267cb = null;268}269}270}271}272273274