View Javadoc
1   /*
2    * Copyright (c) 1994, 2006, Oracle and/or its affiliates. All rights reserved.
3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4    *
5    * This code is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU General Public License version 2 only, as
7    * published by the Free Software Foundation.  Oracle designates this
8    * particular file as subject to the "Classpath" exception as provided
9    * by Oracle in the LICENSE file that accompanied this code.
10   *
11   * This code is distributed in the hope that it will be useful, but WITHOUT
12   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14   * version 2 for more details (a copy is included in the LICENSE file that
15   * accompanied this code).
16   *
17   * You should have received a copy of the GNU General Public License version
18   * 2 along with this work; if not, write to the Free Software Foundation,
19   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20   *
21   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22   * or visit www.oracle.com if you need additional information or have any
23   * questions.
24   */
25  
26  package java.io;
27  
28  /**
29   * A data input stream lets an application read primitive Java data
30   * types from an underlying input stream in a machine-independent
31   * way. An application uses a data output stream to write data that
32   * can later be read by a data input stream.
33   * <p>
34   * DataInputStream is not necessarily safe for multithreaded access.
35   * Thread safety is optional and is the responsibility of users of
36   * methods in this class.
37   *
38   * @author  Arthur van Hoff
39   * @see     java.io.DataOutputStream
40   * @since   JDK1.0
41   */
42  public
43  class DataInputStream extends FilterInputStream implements DataInput {
44  
45      /**
46       * Creates a DataInputStream that uses the specified
47       * underlying InputStream.
48       *
49       * @param  in   the specified input stream
50       */
51      public DataInputStream(InputStream in) {
52          super(in);
53      }
54  
55      /**
56       * working arrays initialized on demand by readUTF
57       */
58      private byte bytearr[] = new byte[80];
59      private char chararr[] = new char[80];
60  
61      /**
62       * Reads some number of bytes from the contained input stream and
63       * stores them into the buffer array <code>b</code>. The number of
64       * bytes actually read is returned as an integer. This method blocks
65       * until input data is available, end of file is detected, or an
66       * exception is thrown.
67       *
68       * <p>If <code>b</code> is null, a <code>NullPointerException</code> is
69       * thrown. If the length of <code>b</code> is zero, then no bytes are
70       * read and <code>0</code> is returned; otherwise, there is an attempt
71       * to read at least one byte. If no byte is available because the
72       * stream is at end of file, the value <code>-1</code> is returned;
73       * otherwise, at least one byte is read and stored into <code>b</code>.
74       *
75       * <p>The first byte read is stored into element <code>b[0]</code>, the
76       * next one into <code>b[1]</code>, and so on. The number of bytes read
77       * is, at most, equal to the length of <code>b</code>. Let <code>k</code>
78       * be the number of bytes actually read; these bytes will be stored in
79       * elements <code>b[0]</code> through <code>b[k-1]</code>, leaving
80       * elements <code>b[k]</code> through <code>b[b.length-1]</code>
81       * unaffected.
82       *
83       * <p>The <code>read(b)</code> method has the same effect as:
84       * <blockquote><pre>
85       * read(b, 0, b.length)
86       * </pre></blockquote>
87       *
88       * @param      b   the buffer into which the data is read.
89       * @return     the total number of bytes read into the buffer, or
90       *             <code>-1</code> if there is no more data because the end
91       *             of the stream has been reached.
92       * @exception  IOException if the first byte cannot be read for any reason
93       * other than end of file, the stream has been closed and the underlying
94       * input stream does not support reading after close, or another I/O
95       * error occurs.
96       * @see        java.io.FilterInputStream#in
97       * @see        java.io.InputStream#read(byte[], int, int)
98       */
99      public final int read(byte b[]) throws IOException {
100         return in.read(b, 0, b.length);
101     }
102 
103     /**
104      * Reads up to <code>len</code> bytes of data from the contained
105      * input stream into an array of bytes.  An attempt is made to read
106      * as many as <code>len</code> bytes, but a smaller number may be read,
107      * possibly zero. The number of bytes actually read is returned as an
108      * integer.
109      *
110      * <p> This method blocks until input data is available, end of file is
111      * detected, or an exception is thrown.
112      *
113      * <p> If <code>len</code> is zero, then no bytes are read and
114      * <code>0</code> is returned; otherwise, there is an attempt to read at
115      * least one byte. If no byte is available because the stream is at end of
116      * file, the value <code>-1</code> is returned; otherwise, at least one
117      * byte is read and stored into <code>b</code>.
118      *
119      * <p> The first byte read is stored into element <code>b[off]</code>, the
120      * next one into <code>b[off+1]</code>, and so on. The number of bytes read
121      * is, at most, equal to <code>len</code>. Let <i>k</i> be the number of
122      * bytes actually read; these bytes will be stored in elements
123      * <code>b[off]</code> through <code>b[off+</code><i>k</i><code>-1]</code>,
124      * leaving elements <code>b[off+</code><i>k</i><code>]</code> through
125      * <code>b[off+len-1]</code> unaffected.
126      *
127      * <p> In every case, elements <code>b[0]</code> through
128      * <code>b[off]</code> and elements <code>b[off+len]</code> through
129      * <code>b[b.length-1]</code> are unaffected.
130      *
131      * @param      b     the buffer into which the data is read.
132      * @param off the start offset in the destination array <code>b</code>
133      * @param      len   the maximum number of bytes read.
134      * @return     the total number of bytes read into the buffer, or
135      *             <code>-1</code> if there is no more data because the end
136      *             of the stream has been reached.
137      * @exception  NullPointerException If <code>b</code> is <code>null</code>.
138      * @exception  IndexOutOfBoundsException If <code>off</code> is negative,
139      * <code>len</code> is negative, or <code>len</code> is greater than
140      * <code>b.length - off</code>
141      * @exception  IOException if the first byte cannot be read for any reason
142      * other than end of file, the stream has been closed and the underlying
143      * input stream does not support reading after close, or another I/O
144      * error occurs.
145      * @see        java.io.FilterInputStream#in
146      * @see        java.io.InputStream#read(byte[], int, int)
147      */
148     public final int read(byte b[], int off, int len) throws IOException {
149         return in.read(b, off, len);
150     }
151 
152     /**
153      * See the general contract of the <code>readFully</code>
154      * method of <code>DataInput</code>.
155      * <p>
156      * Bytes
157      * for this operation are read from the contained
158      * input stream.
159      *
160      * @param      b   the buffer into which the data is read.
161      * @exception  EOFException  if this input stream reaches the end before
162      *             reading all the bytes.
163      * @exception  IOException   the stream has been closed and the contained
164      *             input stream does not support reading after close, or
165      *             another I/O error occurs.
166      * @see        java.io.FilterInputStream#in
167      */
168     public final void readFully(byte b[]) throws IOException {
169         readFully(b, 0, b.length);
170     }
171 
172     /**
173      * See the general contract of the <code>readFully</code>
174      * method of <code>DataInput</code>.
175      * <p>
176      * Bytes
177      * for this operation are read from the contained
178      * input stream.
179      *
180      * @param      b     the buffer into which the data is read.
181      * @param      off   the start offset of the data.
182      * @param      len   the number of bytes to read.
183      * @exception  EOFException  if this input stream reaches the end before
184      *               reading all the bytes.
185      * @exception  IOException   the stream has been closed and the contained
186      *             input stream does not support reading after close, or
187      *             another I/O error occurs.
188      * @see        java.io.FilterInputStream#in
189      */
190     public final void readFully(byte b[], int off, int len) throws IOException {
191         if (len < 0)
192             throw new IndexOutOfBoundsException();
193         int n = 0;
194         while (n < len) {
195             int count = in.read(b, off + n, len - n);
196             if (count < 0)
197                 throw new EOFException();
198             n += count;
199         }
200     }
201 
202     /**
203      * See the general contract of the <code>skipBytes</code>
204      * method of <code>DataInput</code>.
205      * <p>
206      * Bytes for this operation are read from the contained
207      * input stream.
208      *
209      * @param      n   the number of bytes to be skipped.
210      * @return     the actual number of bytes skipped.
211      * @exception  IOException  if the contained input stream does not support
212      *             seek, or the stream has been closed and
213      *             the contained input stream does not support
214      *             reading after close, or another I/O error occurs.
215      */
216     public final int skipBytes(int n) throws IOException {
217         int total = 0;
218         int cur = 0;
219 
220         while ((total<n) && ((cur = (int) in.skip(n-total)) > 0)) {
221             total += cur;
222         }
223 
224         return total;
225     }
226 
227     /**
228      * See the general contract of the <code>readBoolean</code>
229      * method of <code>DataInput</code>.
230      * <p>
231      * Bytes for this operation are read from the contained
232      * input stream.
233      *
234      * @return     the <code>boolean</code> value read.
235      * @exception  EOFException  if this input stream has reached the end.
236      * @exception  IOException   the stream has been closed and the contained
237      *             input stream does not support reading after close, or
238      *             another I/O error occurs.
239      * @see        java.io.FilterInputStream#in
240      */
241     public final boolean readBoolean() throws IOException {
242         int ch = in.read();
243         if (ch < 0)
244             throw new EOFException();
245         return (ch != 0);
246     }
247 
248     /**
249      * See the general contract of the <code>readByte</code>
250      * method of <code>DataInput</code>.
251      * <p>
252      * Bytes
253      * for this operation are read from the contained
254      * input stream.
255      *
256      * @return     the next byte of this input stream as a signed 8-bit
257      *             <code>byte</code>.
258      * @exception  EOFException  if this input stream has reached the end.
259      * @exception  IOException   the stream has been closed and the contained
260      *             input stream does not support reading after close, or
261      *             another I/O error occurs.
262      * @see        java.io.FilterInputStream#in
263      */
264     public final byte readByte() throws IOException {
265         int ch = in.read();
266         if (ch < 0)
267             throw new EOFException();
268         return (byte)(ch);
269     }
270 
271     /**
272      * See the general contract of the <code>readUnsignedByte</code>
273      * method of <code>DataInput</code>.
274      * <p>
275      * Bytes
276      * for this operation are read from the contained
277      * input stream.
278      *
279      * @return     the next byte of this input stream, interpreted as an
280      *             unsigned 8-bit number.
281      * @exception  EOFException  if this input stream has reached the end.
282      * @exception  IOException   the stream has been closed and the contained
283      *             input stream does not support reading after close, or
284      *             another I/O error occurs.
285      * @see         java.io.FilterInputStream#in
286      */
287     public final int readUnsignedByte() throws IOException {
288         int ch = in.read();
289         if (ch < 0)
290             throw new EOFException();
291         return ch;
292     }
293 
294     /**
295      * See the general contract of the <code>readShort</code>
296      * method of <code>DataInput</code>.
297      * <p>
298      * Bytes
299      * for this operation are read from the contained
300      * input stream.
301      *
302      * @return     the next two bytes of this input stream, interpreted as a
303      *             signed 16-bit number.
304      * @exception  EOFException  if this input stream reaches the end before
305      *               reading two bytes.
306      * @exception  IOException   the stream has been closed and the contained
307      *             input stream does not support reading after close, or
308      *             another I/O error occurs.
309      * @see        java.io.FilterInputStream#in
310      */
311     public final short readShort() throws IOException {
312         int ch1 = in.read();
313         int ch2 = in.read();
314         if ((ch1 | ch2) < 0)
315             throw new EOFException();
316         return (short)((ch1 << 8) + (ch2 << 0));
317     }
318 
319     /**
320      * See the general contract of the <code>readUnsignedShort</code>
321      * method of <code>DataInput</code>.
322      * <p>
323      * Bytes
324      * for this operation are read from the contained
325      * input stream.
326      *
327      * @return     the next two bytes of this input stream, interpreted as an
328      *             unsigned 16-bit integer.
329      * @exception  EOFException  if this input stream reaches the end before
330      *             reading two bytes.
331      * @exception  IOException   the stream has been closed and the contained
332      *             input stream does not support reading after close, or
333      *             another I/O error occurs.
334      * @see        java.io.FilterInputStream#in
335      */
336     public final int readUnsignedShort() throws IOException {
337         int ch1 = in.read();
338         int ch2 = in.read();
339         if ((ch1 | ch2) < 0)
340             throw new EOFException();
341         return (ch1 << 8) + (ch2 << 0);
342     }
343 
344     /**
345      * See the general contract of the <code>readChar</code>
346      * method of <code>DataInput</code>.
347      * <p>
348      * Bytes
349      * for this operation are read from the contained
350      * input stream.
351      *
352      * @return     the next two bytes of this input stream, interpreted as a
353      *             <code>char</code>.
354      * @exception  EOFException  if this input stream reaches the end before
355      *               reading two bytes.
356      * @exception  IOException   the stream has been closed and the contained
357      *             input stream does not support reading after close, or
358      *             another I/O error occurs.
359      * @see        java.io.FilterInputStream#in
360      */
361     public final char readChar() throws IOException {
362         int ch1 = in.read();
363         int ch2 = in.read();
364         if ((ch1 | ch2) < 0)
365             throw new EOFException();
366         return (char)((ch1 << 8) + (ch2 << 0));
367     }
368 
369     /**
370      * See the general contract of the <code>readInt</code>
371      * method of <code>DataInput</code>.
372      * <p>
373      * Bytes
374      * for this operation are read from the contained
375      * input stream.
376      *
377      * @return     the next four bytes of this input stream, interpreted as an
378      *             <code>int</code>.
379      * @exception  EOFException  if this input stream reaches the end before
380      *               reading four bytes.
381      * @exception  IOException   the stream has been closed and the contained
382      *             input stream does not support reading after close, or
383      *             another I/O error occurs.
384      * @see        java.io.FilterInputStream#in
385      */
386     public final int readInt() throws IOException {
387         int ch1 = in.read();
388         int ch2 = in.read();
389         int ch3 = in.read();
390         int ch4 = in.read();
391         if ((ch1 | ch2 | ch3 | ch4) < 0)
392             throw new EOFException();
393         return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
394     }
395 
396     private byte readBuffer[] = new byte[8];
397 
398     /**
399      * See the general contract of the <code>readLong</code>
400      * method of <code>DataInput</code>.
401      * <p>
402      * Bytes
403      * for this operation are read from the contained
404      * input stream.
405      *
406      * @return     the next eight bytes of this input stream, interpreted as a
407      *             <code>long</code>.
408      * @exception  EOFException  if this input stream reaches the end before
409      *               reading eight bytes.
410      * @exception  IOException   the stream has been closed and the contained
411      *             input stream does not support reading after close, or
412      *             another I/O error occurs.
413      * @see        java.io.FilterInputStream#in
414      */
415     public final long readLong() throws IOException {
416         readFully(readBuffer, 0, 8);
417         return (((long)readBuffer[0] << 56) +
418                 ((long)(readBuffer[1] & 255) << 48) +
419                 ((long)(readBuffer[2] & 255) << 40) +
420                 ((long)(readBuffer[3] & 255) << 32) +
421                 ((long)(readBuffer[4] & 255) << 24) +
422                 ((readBuffer[5] & 255) << 16) +
423                 ((readBuffer[6] & 255) <<  8) +
424                 ((readBuffer[7] & 255) <<  0));
425     }
426 
427     /**
428      * See the general contract of the <code>readFloat</code>
429      * method of <code>DataInput</code>.
430      * <p>
431      * Bytes
432      * for this operation are read from the contained
433      * input stream.
434      *
435      * @return     the next four bytes of this input stream, interpreted as a
436      *             <code>float</code>.
437      * @exception  EOFException  if this input stream reaches the end before
438      *               reading four bytes.
439      * @exception  IOException   the stream has been closed and the contained
440      *             input stream does not support reading after close, or
441      *             another I/O error occurs.
442      * @see        java.io.DataInputStream#readInt()
443      * @see        java.lang.Float#intBitsToFloat(int)
444      */
445     public final float readFloat() throws IOException {
446         return Float.intBitsToFloat(readInt());
447     }
448 
449     /**
450      * See the general contract of the <code>readDouble</code>
451      * method of <code>DataInput</code>.
452      * <p>
453      * Bytes
454      * for this operation are read from the contained
455      * input stream.
456      *
457      * @return     the next eight bytes of this input stream, interpreted as a
458      *             <code>double</code>.
459      * @exception  EOFException  if this input stream reaches the end before
460      *               reading eight bytes.
461      * @exception  IOException   the stream has been closed and the contained
462      *             input stream does not support reading after close, or
463      *             another I/O error occurs.
464      * @see        java.io.DataInputStream#readLong()
465      * @see        java.lang.Double#longBitsToDouble(long)
466      */
467     public final double readDouble() throws IOException {
468         return Double.longBitsToDouble(readLong());
469     }
470 
471     private char lineBuffer[];
472 
473     /**
474      * See the general contract of the <code>readLine</code>
475      * method of <code>DataInput</code>.
476      * <p>
477      * Bytes
478      * for this operation are read from the contained
479      * input stream.
480      *
481      * @deprecated This method does not properly convert bytes to characters.
482      * As of JDK&nbsp;1.1, the preferred way to read lines of text is via the
483      * <code>BufferedReader.readLine()</code> method.  Programs that use the
484      * <code>DataInputStream</code> class to read lines can be converted to use
485      * the <code>BufferedReader</code> class by replacing code of the form:
486      * <blockquote><pre>
487      *     DataInputStream d =&nbsp;new&nbsp;DataInputStream(in);
488      * </pre></blockquote>
489      * with:
490      * <blockquote><pre>
491      *     BufferedReader d
492      *          =&nbsp;new&nbsp;BufferedReader(new&nbsp;InputStreamReader(in));
493      * </pre></blockquote>
494      *
495      * @return     the next line of text from this input stream.
496      * @exception  IOException  if an I/O error occurs.
497      * @see        java.io.BufferedReader#readLine()
498      * @see        java.io.FilterInputStream#in
499      */
500     @Deprecated
501     public final String readLine() throws IOException {
502         char buf[] = lineBuffer;
503 
504         if (buf == null) {
505             buf = lineBuffer = new char[128];
506         }
507 
508         int room = buf.length;
509         int offset = 0;
510         int c;
511 
512 loop:   while (true) {
513             switch (c = in.read()) {
514               case -1:
515               case '\n':
516                 break loop;
517 
518               case '\r':
519                 int c2 = in.read();
520                 if ((c2 != '\n') && (c2 != -1)) {
521                     if (!(in instanceof PushbackInputStream)) {
522                         this.in = new PushbackInputStream(in);
523                     }
524                     ((PushbackInputStream)in).unread(c2);
525                 }
526                 break loop;
527 
528               default:
529                 if (--room < 0) {
530                     buf = new char[offset + 128];
531                     room = buf.length - offset - 1;
532                     System.arraycopy(lineBuffer, 0, buf, 0, offset);
533                     lineBuffer = buf;
534                 }
535                 buf[offset++] = (char) c;
536                 break;
537             }
538         }
539         if ((c == -1) && (offset == 0)) {
540             return null;
541         }
542         return String.copyValueOf(buf, 0, offset);
543     }
544 
545     /**
546      * See the general contract of the <code>readUTF</code>
547      * method of <code>DataInput</code>.
548      * <p>
549      * Bytes
550      * for this operation are read from the contained
551      * input stream.
552      *
553      * @return     a Unicode string.
554      * @exception  EOFException  if this input stream reaches the end before
555      *               reading all the bytes.
556      * @exception  IOException   the stream has been closed and the contained
557      *             input stream does not support reading after close, or
558      *             another I/O error occurs.
559      * @exception  UTFDataFormatException if the bytes do not represent a valid
560      *             modified UTF-8 encoding of a string.
561      * @see        java.io.DataInputStream#readUTF(java.io.DataInput)
562      */
563     public final String readUTF() throws IOException {
564         return readUTF(this);
565     }
566 
567     /**
568      * Reads from the
569      * stream <code>in</code> a representation
570      * of a Unicode  character string encoded in
571      * <a href="DataInput.html#modified-utf-8">modified UTF-8</a> format;
572      * this string of characters is then returned as a <code>String</code>.
573      * The details of the modified UTF-8 representation
574      * are  exactly the same as for the <code>readUTF</code>
575      * method of <code>DataInput</code>.
576      *
577      * @param      in   a data input stream.
578      * @return     a Unicode string.
579      * @exception  EOFException            if the input stream reaches the end
580      *               before all the bytes.
581      * @exception  IOException   the stream has been closed and the contained
582      *             input stream does not support reading after close, or
583      *             another I/O error occurs.
584      * @exception  UTFDataFormatException  if the bytes do not represent a
585      *               valid modified UTF-8 encoding of a Unicode string.
586      * @see        java.io.DataInputStream#readUnsignedShort()
587      */
588     public final static String readUTF(DataInput in) throws IOException {
589         int utflen = in.readUnsignedShort();
590         byte[] bytearr = null;
591         char[] chararr = null;
592         if (in instanceof DataInputStream) {
593             DataInputStream dis = (DataInputStream)in;
594             if (dis.bytearr.length < utflen){
595                 dis.bytearr = new byte[utflen*2];
596                 dis.chararr = new char[utflen*2];
597             }
598             chararr = dis.chararr;
599             bytearr = dis.bytearr;
600         } else {
601             bytearr = new byte[utflen];
602             chararr = new char[utflen];
603         }
604 
605         int c, char2, char3;
606         int count = 0;
607         int chararr_count=0;
608 
609         in.readFully(bytearr, 0, utflen);
610 
611         while (count < utflen) {
612             c = (int) bytearr[count] & 0xff;
613             if (c > 127) break;
614             count++;
615             chararr[chararr_count++]=(char)c;
616         }
617 
618         while (count < utflen) {
619             c = (int) bytearr[count] & 0xff;
620             switch (c >> 4) {
621                 case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
622                     /* 0xxxxxxx*/
623                     count++;
624                     chararr[chararr_count++]=(char)c;
625                     break;
626                 case 12: case 13:
627                     /* 110x xxxx   10xx xxxx*/
628                     count += 2;
629                     if (count > utflen)
630                         throw new UTFDataFormatException(
631                             "malformed input: partial character at end");
632                     char2 = (int) bytearr[count-1];
633                     if ((char2 & 0xC0) != 0x80)
634                         throw new UTFDataFormatException(
635                             "malformed input around byte " + count);
636                     chararr[chararr_count++]=(char)(((c & 0x1F) << 6) |
637                                                     (char2 & 0x3F));
638                     break;
639                 case 14:
640                     /* 1110 xxxx  10xx xxxx  10xx xxxx */
641                     count += 3;
642                     if (count > utflen)
643                         throw new UTFDataFormatException(
644                             "malformed input: partial character at end");
645                     char2 = (int) bytearr[count-2];
646                     char3 = (int) bytearr[count-1];
647                     if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80))
648                         throw new UTFDataFormatException(
649                             "malformed input around byte " + (count-1));
650                     chararr[chararr_count++]=(char)(((c     & 0x0F) << 12) |
651                                                     ((char2 & 0x3F) << 6)  |
652                                                     ((char3 & 0x3F) << 0));
653                     break;
654                 default:
655                     /* 10xx xxxx,  1111 xxxx */
656                     throw new UTFDataFormatException(
657                         "malformed input around byte " + count);
658             }
659         }
660         // The number of chars produced may be less than utflen
661         return new String(chararr, 0, chararr_count);
662     }
663 }