KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > io > DataOutputStream


1 /*
2  * @(#)DataOutputStream.java 1.43 04/05/13
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  * A data output stream lets an application write primitive Java data
12  * types to an output stream in a portable way. An application can
13  * then use a data input stream to read the data back in.
14  *
15  * @author unascribed
16  * @version 1.43, 05/13/04
17  * @see java.io.DataInputStream
18  * @since JDK1.0
19  */

20 public
21 class DataOutputStream extends FilterOutputStream JavaDoc implements DataOutput JavaDoc {
22     /**
23      * The number of bytes written to the data output stream so far.
24      * If this counter overflows, it will be wrapped to Integer.MAX_VALUE.
25      */

26     protected int written;
27
28     /**
29      * bytearr is initialized on demand by writeUTF
30      */

31     private byte[] bytearr = null;
32
33     /**
34      * Creates a new data output stream to write data to the specified
35      * underlying output stream. The counter <code>written</code> is
36      * set to zero.
37      *
38      * @param out the underlying output stream, to be saved for later
39      * use.
40      * @see java.io.FilterOutputStream#out
41      */

42     public DataOutputStream(OutputStream JavaDoc out) {
43     super(out);
44     }
45
46     /**
47      * Increases the written counter by the specified value
48      * until it reaches Integer.MAX_VALUE.
49      */

50     private void incCount(int value) {
51         int temp = written + value;
52         if (temp < 0) {
53             temp = Integer.MAX_VALUE;
54         }
55         written = temp;
56     }
57
58     /**
59      * Writes the specified byte (the low eight bits of the argument
60      * <code>b</code>) to the underlying output stream. If no exception
61      * is thrown, the counter <code>written</code> is incremented by
62      * <code>1</code>.
63      * <p>
64      * Implements the <code>write</code> method of <code>OutputStream</code>.
65      *
66      * @param b the <code>byte</code> to be written.
67      * @exception IOException if an I/O error occurs.
68      * @see java.io.FilterOutputStream#out
69      */

70     public synchronized void write(int b) throws IOException JavaDoc {
71     out.write(b);
72         incCount(1);
73     }
74
75     /**
76      * Writes <code>len</code> bytes from the specified byte array
77      * starting at offset <code>off</code> to the underlying output stream.
78      * If no exception is thrown, the counter <code>written</code> is
79      * incremented by <code>len</code>.
80      *
81      * @param b the data.
82      * @param off the start offset in the data.
83      * @param len the number of bytes to write.
84      * @exception IOException if an I/O error occurs.
85      * @see java.io.FilterOutputStream#out
86      */

87     public synchronized void write(byte b[], int off, int len)
88     throws IOException JavaDoc
89     {
90     out.write(b, off, len);
91     incCount(len);
92     }
93
94     /**
95      * Flushes this data output stream. This forces any buffered output
96      * bytes to be written out to the stream.
97      * <p>
98      * The <code>flush</code> method of <code>DataOutputStream</code>
99      * calls the <code>flush</code> method of its underlying output stream.
100      *
101      * @exception IOException if an I/O error occurs.
102      * @see java.io.FilterOutputStream#out
103      * @see java.io.OutputStream#flush()
104      */

105     public void flush() throws IOException JavaDoc {
106     out.flush();
107     }
108
109     /**
110      * Writes a <code>boolean</code> to the underlying output stream as
111      * a 1-byte value. The value <code>true</code> is written out as the
112      * value <code>(byte)1</code>; the value <code>false</code> is
113      * written out as the value <code>(byte)0</code>. If no exception is
114      * thrown, the counter <code>written</code> is incremented by
115      * <code>1</code>.
116      *
117      * @param v a <code>boolean</code> value to be written.
118      * @exception IOException if an I/O error occurs.
119      * @see java.io.FilterOutputStream#out
120      */

121     public final void writeBoolean(boolean v) throws IOException JavaDoc {
122     out.write(v ? 1 : 0);
123     incCount(1);
124     }
125
126     /**
127      * Writes out a <code>byte</code> to the underlying output stream as
128      * a 1-byte value. If no exception is thrown, the counter
129      * <code>written</code> is incremented by <code>1</code>.
130      *
131      * @param v a <code>byte</code> value to be written.
132      * @exception IOException if an I/O error occurs.
133      * @see java.io.FilterOutputStream#out
134      */

135     public final void writeByte(int v) throws IOException JavaDoc {
136     out.write(v);
137         incCount(1);
138     }
139
140     /**
141      * Writes a <code>short</code> to the underlying output stream as two
142      * bytes, high byte first. If no exception is thrown, the counter
143      * <code>written</code> is incremented by <code>2</code>.
144      *
145      * @param v a <code>short</code> to be written.
146      * @exception IOException if an I/O error occurs.
147      * @see java.io.FilterOutputStream#out
148      */

149     public final void writeShort(int v) throws IOException JavaDoc {
150         out.write((v >>> 8) & 0xFF);
151         out.write((v >>> 0) & 0xFF);
152         incCount(2);
153     }
154
155     /**
156      * Writes a <code>char</code> to the underlying output stream as a
157      * 2-byte value, high byte first. If no exception is thrown, the
158      * counter <code>written</code> is incremented by <code>2</code>.
159      *
160      * @param v a <code>char</code> value to be written.
161      * @exception IOException if an I/O error occurs.
162      * @see java.io.FilterOutputStream#out
163      */

164     public final void writeChar(int v) throws IOException JavaDoc {
165         out.write((v >>> 8) & 0xFF);
166         out.write((v >>> 0) & 0xFF);
167         incCount(2);
168     }
169
170     /**
171      * Writes an <code>int</code> to the underlying output stream as four
172      * bytes, high byte first. If no exception is thrown, the counter
173      * <code>written</code> is incremented by <code>4</code>.
174      *
175      * @param v an <code>int</code> to be written.
176      * @exception IOException if an I/O error occurs.
177      * @see java.io.FilterOutputStream#out
178      */

179     public final void writeInt(int v) throws IOException JavaDoc {
180         out.write((v >>> 24) & 0xFF);
181         out.write((v >>> 16) & 0xFF);
182         out.write((v >>> 8) & 0xFF);
183         out.write((v >>> 0) & 0xFF);
184         incCount(4);
185     }
186
187     private byte writeBuffer[] = new byte[8];
188
189     /**
190      * Writes a <code>long</code> to the underlying output stream as eight
191      * bytes, high byte first. In no exception is thrown, the counter
192      * <code>written</code> is incremented by <code>8</code>.
193      *
194      * @param v a <code>long</code> to be written.
195      * @exception IOException if an I/O error occurs.
196      * @see java.io.FilterOutputStream#out
197      */

198     public final void writeLong(long v) throws IOException JavaDoc {
199         writeBuffer[0] = (byte)(v >>> 56);
200         writeBuffer[1] = (byte)(v >>> 48);
201         writeBuffer[2] = (byte)(v >>> 40);
202         writeBuffer[3] = (byte)(v >>> 32);
203         writeBuffer[4] = (byte)(v >>> 24);
204         writeBuffer[5] = (byte)(v >>> 16);
205         writeBuffer[6] = (byte)(v >>> 8);
206         writeBuffer[7] = (byte)(v >>> 0);
207         out.write(writeBuffer, 0, 8);
208     incCount(8);
209     }
210
211     /**
212      * Converts the float argument to an <code>int</code> using the
213      * <code>floatToIntBits</code> method in class <code>Float</code>,
214      * and then writes that <code>int</code> value to the underlying
215      * output stream as a 4-byte quantity, high byte first. If no
216      * exception is thrown, the counter <code>written</code> is
217      * incremented by <code>4</code>.
218      *
219      * @param v a <code>float</code> value to be written.
220      * @exception IOException if an I/O error occurs.
221      * @see java.io.FilterOutputStream#out
222      * @see java.lang.Float#floatToIntBits(float)
223      */

224     public final void writeFloat(float v) throws IOException JavaDoc {
225     writeInt(Float.floatToIntBits(v));
226     }
227
228     /**
229      * Converts the double argument to a <code>long</code> using the
230      * <code>doubleToLongBits</code> method in class <code>Double</code>,
231      * and then writes that <code>long</code> value to the underlying
232      * output stream as an 8-byte quantity, high byte first. If no
233      * exception is thrown, the counter <code>written</code> is
234      * incremented by <code>8</code>.
235      *
236      * @param v a <code>double</code> value to be written.
237      * @exception IOException if an I/O error occurs.
238      * @see java.io.FilterOutputStream#out
239      * @see java.lang.Double#doubleToLongBits(double)
240      */

241     public final void writeDouble(double v) throws IOException JavaDoc {
242     writeLong(Double.doubleToLongBits(v));
243     }
244
245     /**
246      * Writes out the string to the underlying output stream as a
247      * sequence of bytes. Each character in the string is written out, in
248      * sequence, by discarding its high eight bits. If no exception is
249      * thrown, the counter <code>written</code> is incremented by the
250      * length of <code>s</code>.
251      *
252      * @param s a string of bytes to be written.
253      * @exception IOException if an I/O error occurs.
254      * @see java.io.FilterOutputStream#out
255      */

256     public final void writeBytes(String JavaDoc s) throws IOException JavaDoc {
257     int len = s.length();
258     for (int i = 0 ; i < len ; i++) {
259         out.write((byte)s.charAt(i));
260     }
261     incCount(len);
262     }
263
264     /**
265      * Writes a string to the underlying output stream as a sequence of
266      * characters. Each character is written to the data output stream as
267      * if by the <code>writeChar</code> method. If no exception is
268      * thrown, the counter <code>written</code> is incremented by twice
269      * the length of <code>s</code>.
270      *
271      * @param s a <code>String</code> value to be written.
272      * @exception IOException if an I/O error occurs.
273      * @see java.io.DataOutputStream#writeChar(int)
274      * @see java.io.FilterOutputStream#out
275      */

276     public final void writeChars(String JavaDoc s) throws IOException JavaDoc {
277         int len = s.length();
278         for (int i = 0 ; i < len ; i++) {
279             int v = s.charAt(i);
280             out.write((v >>> 8) & 0xFF);
281             out.write((v >>> 0) & 0xFF);
282         }
283         incCount(len * 2);
284     }
285
286     /**
287      * Writes a string to the underlying output stream using
288      * <a HREF="DataInput.html#modified-utf-8">modified UTF-8</a>
289      * encoding in a machine-independent manner.
290      * <p>
291      * First, two bytes are written to the output stream as if by the
292      * <code>writeShort</code> method giving the number of bytes to
293      * follow. This value is the number of bytes actually written out,
294      * not the length of the string. Following the length, each character
295      * of the string is output, in sequence, using the modified UTF-8 encoding
296      * for the character. If no exception is thrown, the counter
297      * <code>written</code> is incremented by the total number of
298      * bytes written to the output stream. This will be at least two
299      * plus the length of <code>str</code>, and at most two plus
300      * thrice the length of <code>str</code>.
301      *
302      * @param str a string to be written.
303      * @exception IOException if an I/O error occurs.
304      */

305     public final void writeUTF(String JavaDoc str) throws IOException JavaDoc {
306         writeUTF(str, this);
307     }
308
309     /**
310      * Writes a string to the specified DataOutput using
311      * <a HREF="DataInput.html#modified-utf-8">modified UTF-8</a>
312      * encoding in a machine-independent manner.
313      * <p>
314      * First, two bytes are written to out as if by the <code>writeShort</code>
315      * method giving the number of bytes to follow. This value is the number of
316      * bytes actually written out, not the length of the string. Following the
317      * length, each character of the string is output, in sequence, using the
318      * modified UTF-8 encoding for the character. If no exception is thrown, the
319      * counter <code>written</code> is incremented by the total number of
320      * bytes written to the output stream. This will be at least two
321      * plus the length of <code>str</code>, and at most two plus
322      * thrice the length of <code>str</code>.
323      *
324      * @param str a string to be written.
325      * @param out destination to write to
326      * @return The number of bytes written out.
327      * @exception IOException if an I/O error occurs.
328      */

329     static int writeUTF(String JavaDoc str, DataOutput JavaDoc out) throws IOException JavaDoc {
330         int strlen = str.length();
331     int utflen = 0;
332     int c, count = 0;
333  
334         /* use charAt instead of copying String to char array */
335     for (int i = 0; i < strlen; i++) {
336             c = str.charAt(i);
337         if ((c >= 0x0001) && (c <= 0x007F)) {
338         utflen++;
339         } else if (c > 0x07FF) {
340         utflen += 3;
341         } else {
342         utflen += 2;
343         }
344     }
345
346     if (utflen > 65535)
347         throw new UTFDataFormatException JavaDoc(
348                 "encoded string too long: " + utflen + " bytes");
349
350         byte[] bytearr = null;
351         if (out instanceof DataOutputStream JavaDoc) {
352             DataOutputStream JavaDoc dos = (DataOutputStream JavaDoc)out;
353             if(dos.bytearr == null || (dos.bytearr.length < (utflen+2)))
354                 dos.bytearr = new byte[(utflen*2) + 2];
355             bytearr = dos.bytearr;
356         } else {
357             bytearr = new byte[utflen+2];
358         }
359      
360     bytearr[count++] = (byte) ((utflen >>> 8) & 0xFF);
361     bytearr[count++] = (byte) ((utflen >>> 0) & 0xFF);
362         
363         int i=0;
364         for (i=0; i<strlen; i++) {
365            c = str.charAt(i);
366            if (!((c >= 0x0001) && (c <= 0x007F))) break;
367            bytearr[count++] = (byte) c;
368         }
369     
370     for (;i < strlen; i++){
371             c = str.charAt(i);
372         if ((c >= 0x0001) && (c <= 0x007F)) {
373         bytearr[count++] = (byte) c;
374                
375         } else if (c > 0x07FF) {
376         bytearr[count++] = (byte) (0xE0 | ((c >> 12) & 0x0F));
377         bytearr[count++] = (byte) (0x80 | ((c >> 6) & 0x3F));
378         bytearr[count++] = (byte) (0x80 | ((c >> 0) & 0x3F));
379         } else {
380         bytearr[count++] = (byte) (0xC0 | ((c >> 6) & 0x1F));
381         bytearr[count++] = (byte) (0x80 | ((c >> 0) & 0x3F));
382         }
383     }
384         out.write(bytearr, 0, utflen+2);
385         return utflen + 2;
386     }
387
388     /**
389      * Returns the current value of the counter <code>written</code>,
390      * the number of bytes written to this data output stream so far.
391      * If the counter overflows, it will be wrapped to Integer.MAX_VALUE.
392      *
393      * @return the value of the <code>written</code> field.
394      * @see java.io.DataOutputStream#written
395      */

396     public final int size() {
397     return written;
398     }
399 }
400
Popular Tags