KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > io > BufferedWriter


1 /*
2  * @(#)BufferedWriter.java 1.26 03/12/19
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package java.io;
9
10
11 /**
12  * Write text to a character-output stream, buffering characters so as to
13  * provide for the efficient writing of single characters, arrays, and strings.
14  *
15  * <p> The buffer size may be specified, or the default size may be accepted.
16  * The default is large enough for most purposes.
17  *
18  * <p> A newLine() method is provided, which uses the platform's own notion of
19  * line separator as defined by the system property <tt>line.separator</tt>.
20  * Not all platforms use the newline character ('\n') to terminate lines.
21  * Calling this method to terminate each output line is therefore preferred to
22  * writing a newline character directly.
23  *
24  * <p> In general, a Writer sends its output immediately to the underlying
25  * character or byte stream. Unless prompt output is required, it is advisable
26  * to wrap a BufferedWriter around any Writer whose write() operations may be
27  * costly, such as FileWriters and OutputStreamWriters. For example,
28  *
29  * <pre>
30  * PrintWriter out
31  * = new PrintWriter(new BufferedWriter(new FileWriter("foo.out")));
32  * </pre>
33  *
34  * will buffer the PrintWriter's output to the file. Without buffering, each
35  * invocation of a print() method would cause characters to be converted into
36  * bytes that would then be written immediately to the file, which can be very
37  * inefficient.
38  *
39  * @see PrintWriter
40  * @see FileWriter
41  * @see OutputStreamWriter
42  *
43  * @version 1.26, 03/12/19
44  * @author Mark Reinhold
45  * @since JDK1.1
46  */

47
48 public class BufferedWriter extends Writer JavaDoc {
49
50     private Writer JavaDoc out;
51
52     private char cb[];
53     private int nChars, nextChar;
54
55     private static int defaultCharBufferSize = 8192;
56
57     /**
58      * Line separator string. This is the value of the line.separator
59      * property at the moment that the stream was created.
60      */

61     private String JavaDoc lineSeparator;
62
63     /**
64      * Create a buffered character-output stream that uses a default-sized
65      * output buffer.
66      *
67      * @param out A Writer
68      */

69     public BufferedWriter(Writer JavaDoc out) {
70     this(out, defaultCharBufferSize);
71     }
72
73     /**
74      * Create a new buffered character-output stream that uses an output
75      * buffer of the given size.
76      *
77      * @param out A Writer
78      * @param sz Output-buffer size, a positive integer
79      *
80      * @exception IllegalArgumentException If sz is <= 0
81      */

82     public BufferedWriter(Writer JavaDoc out, int sz) {
83     super(out);
84     if (sz <= 0)
85         throw new IllegalArgumentException JavaDoc("Buffer size <= 0");
86     this.out = out;
87     cb = new char[sz];
88     nChars = sz;
89     nextChar = 0;
90
91     lineSeparator = (String JavaDoc) java.security.AccessController.doPrivileged(
92                new sun.security.action.GetPropertyAction("line.separator"));
93     }
94
95     /** Check to make sure that the stream has not been closed */
96     private void ensureOpen() throws IOException JavaDoc {
97     if (out == null)
98         throw new IOException JavaDoc("Stream closed");
99     }
100
101     /**
102      * Flush the output buffer to the underlying character stream, without
103      * flushing the stream itself. This method is non-private only so that it
104      * may be invoked by PrintStream.
105      */

106     void flushBuffer() throws IOException JavaDoc {
107     synchronized (lock) {
108         ensureOpen();
109         if (nextChar == 0)
110         return;
111         out.write(cb, 0, nextChar);
112         nextChar = 0;
113     }
114     }
115
116     /**
117      * Write a single character.
118      *
119      * @exception IOException If an I/O error occurs
120      */

121     public void write(int c) throws IOException JavaDoc {
122     synchronized (lock) {
123         ensureOpen();
124         if (nextChar >= nChars)
125         flushBuffer();
126         cb[nextChar++] = (char) c;
127     }
128     }
129
130     /**
131      * Our own little min method, to avoid loading java.lang.Math if we've run
132      * out of file descriptors and we're trying to print a stack trace.
133      */

134     private int min(int a, int b) {
135     if (a < b) return a;
136     return b;
137     }
138
139     /**
140      * Write a portion of an array of characters.
141      *
142      * <p> Ordinarily this method stores characters from the given array into
143      * this stream's buffer, flushing the buffer to the underlying stream as
144      * needed. If the requested length is at least as large as the buffer,
145      * however, then this method will flush the buffer and write the characters
146      * directly to the underlying stream. Thus redundant
147      * <code>BufferedWriter</code>s will not copy data unnecessarily.
148      *
149      * @param cbuf A character array
150      * @param off Offset from which to start reading characters
151      * @param len Number of characters to write
152      *
153      * @exception IOException If an I/O error occurs
154      */

155     public void write(char cbuf[], int off, int len) throws IOException JavaDoc {
156     synchronized (lock) {
157         ensureOpen();
158             if ((off < 0) || (off > cbuf.length) || (len < 0) ||
159                 ((off + len) > cbuf.length) || ((off + len) < 0)) {
160                 throw new IndexOutOfBoundsException JavaDoc();
161             } else if (len == 0) {
162                 return;
163             }
164
165         if (len >= nChars) {
166         /* If the request length exceeds the size of the output buffer,
167            flush the buffer and then write the data directly. In this
168            way buffered streams will cascade harmlessly. */

169         flushBuffer();
170         out.write(cbuf, off, len);
171         return;
172         }
173
174         int b = off, t = off + len;
175         while (b < t) {
176         int d = min(nChars - nextChar, t - b);
177         System.arraycopy(cbuf, b, cb, nextChar, d);
178         b += d;
179         nextChar += d;
180         if (nextChar >= nChars)
181             flushBuffer();
182         }
183     }
184     }
185
186     /**
187      * Write a portion of a String.
188      *
189      * <p> If the value of the <tt>len</tt> parameter is negative then no
190      * characters are written. This is contrary to the specification of this
191      * method in the {@linkplain java.io.Writer#write(java.lang.String,int,int)
192      * superclass}, which requires that an {@link IndexOutOfBoundsException} be
193      * thrown.
194      *
195      * @param s String to be written
196      * @param off Offset from which to start reading characters
197      * @param len Number of characters to be written
198      *
199      * @exception IOException If an I/O error occurs
200      */

201     public void write(String JavaDoc s, int off, int len) throws IOException JavaDoc {
202     synchronized (lock) {
203         ensureOpen();
204
205         int b = off, t = off + len;
206         while (b < t) {
207         int d = min(nChars - nextChar, t - b);
208         s.getChars(b, b + d, cb, nextChar);
209         b += d;
210         nextChar += d;
211         if (nextChar >= nChars)
212             flushBuffer();
213         }
214     }
215     }
216
217     /**
218      * Write a line separator. The line separator string is defined by the
219      * system property <tt>line.separator</tt>, and is not necessarily a single
220      * newline ('\n') character.
221      *
222      * @exception IOException If an I/O error occurs
223      */

224     public void newLine() throws IOException JavaDoc {
225     write(lineSeparator);
226     }
227
228     /**
229      * Flush the stream.
230      *
231      * @exception IOException If an I/O error occurs
232      */

233     public void flush() throws IOException JavaDoc {
234     synchronized (lock) {
235         flushBuffer();
236         out.flush();
237     }
238     }
239
240     /**
241      * Close the stream.
242      *
243      * @exception IOException If an I/O error occurs
244      */

245     public void close() throws IOException JavaDoc {
246     synchronized (lock) {
247         if (out == null)
248         return;
249         flushBuffer();
250         out.close();
251         out = null;
252         cb = null;
253     }
254     }
255
256 }
257
Popular Tags