Path: blob/master/src/java.base/share/classes/java/io/DataInputStream.java
41152 views
/*1* Copyright (c) 1994, 2021, 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;2627import java.util.Objects;2829/**30* A data input stream lets an application read primitive Java data31* types from an underlying input stream in a machine-independent32* way. An application uses a data output stream to write data that33* can later be read by a data input stream.34* <p>35* A DataInputStream is not safe for use by multiple concurrent36* threads. If a DataInputStream is to be used by more than one37* thread then access to the data input stream should be controlled38* by appropriate synchronization.39*40* @author Arthur van Hoff41* @see java.io.DataOutputStream42* @since 1.043*/44public class DataInputStream extends FilterInputStream implements DataInput {4546/**47* Creates a DataInputStream that uses the specified48* underlying InputStream.49*50* @param in the specified input stream51*/52public DataInputStream(InputStream in) {53super(in);54}5556/**57* working arrays initialized on demand by readUTF58*/59private byte bytearr[] = new byte[80];60private char chararr[] = new char[80];6162/**63* Reads some number of bytes from the contained input stream and64* stores them into the buffer array {@code b}. The number of65* bytes actually read is returned as an integer. This method blocks66* until input data is available, end of file is detected, or an67* exception is thrown.68*69* <p>If {@code b} is null, a {@code NullPointerException} is70* thrown. If the length of {@code b} is zero, then no bytes are71* read and {@code 0} is returned; otherwise, there is an attempt72* to read at least one byte. If no byte is available because the73* stream is at end of file, the value {@code -1} is returned;74* otherwise, at least one byte is read and stored into {@code b}.75*76* <p>The first byte read is stored into element {@code b[0]}, the77* next one into {@code b[1]}, and so on. The number of bytes read78* is, at most, equal to the length of {@code b}. Let {@code k}79* be the number of bytes actually read; these bytes will be stored in80* elements {@code b[0]} through {@code b[k-1]}, leaving81* elements {@code b[k]} through {@code b[b.length-1]}82* unaffected.83*84* <p>The {@code read(b)} method has the same effect as:85* <blockquote><pre>86* read(b, 0, b.length)87* </pre></blockquote>88*89* @param b the buffer into which the data is read.90* @return the total number of bytes read into the buffer, or91* {@code -1} if there is no more data because the end92* of the stream has been reached.93* @throws IOException if the first byte cannot be read for any reason94* other than end of file, the stream has been closed and the underlying95* input stream does not support reading after close, or another I/O96* error occurs.97* @see java.io.FilterInputStream#in98* @see java.io.InputStream#read(byte[], int, int)99*/100public final int read(byte b[]) throws IOException {101return in.read(b, 0, b.length);102}103104/**105* Reads up to {@code len} bytes of data from the contained106* input stream into an array of bytes. An attempt is made to read107* as many as {@code len} bytes, but a smaller number may be read,108* possibly zero. The number of bytes actually read is returned as an109* integer.110*111* <p> This method blocks until input data is available, end of file is112* detected, or an exception is thrown.113*114* <p> If {@code len} is zero, then no bytes are read and115* {@code 0} is returned; otherwise, there is an attempt to read at116* least one byte. If no byte is available because the stream is at end of117* file, the value {@code -1} is returned; otherwise, at least one118* byte is read and stored into {@code b}.119*120* <p> The first byte read is stored into element {@code b[off]}, the121* next one into {@code b[off+1]}, and so on. The number of bytes read122* is, at most, equal to {@code len}. Let <i>k</i> be the number of123* bytes actually read; these bytes will be stored in elements124* {@code b[off]} through {@code b[off+}<i>k</i>{@code -1]},125* leaving elements {@code b[off+}<i>k</i>{@code ]} through126* {@code b[off+len-1]} unaffected.127*128* <p> In every case, elements {@code b[0]} through129* {@code b[off]} and elements {@code b[off+len]} through130* {@code b[b.length-1]} are unaffected.131*132* @param b the buffer into which the data is read.133* @param off the start offset in the destination array {@code b}134* @param len the maximum number of bytes read.135* @return the total number of bytes read into the buffer, or136* {@code -1} if there is no more data because the end137* of the stream has been reached.138* @throws NullPointerException If {@code b} is {@code null}.139* @throws IndexOutOfBoundsException If {@code off} is negative,140* {@code len} is negative, or {@code len} is greater than141* {@code b.length - off}142* @throws IOException if the first byte cannot be read for any reason143* other than end of file, the stream has been closed and the underlying144* input stream does not support reading after close, or another I/O145* error occurs.146* @see java.io.FilterInputStream#in147* @see java.io.InputStream#read(byte[], int, int)148*/149public final int read(byte b[], int off, int len) throws IOException {150return in.read(b, off, len);151}152153/**154* See the general contract of the {@code readFully}155* method of {@code DataInput}.156* <p>157* Bytes158* for this operation are read from the contained159* input stream.160*161* @param b the buffer into which the data is read.162* @throws NullPointerException if {@code b} is {@code null}.163* @throws EOFException if this input stream reaches the end before164* reading all the bytes.165* @throws IOException the stream has been closed and the contained166* input stream does not support reading after close, or167* another I/O error occurs.168* @see java.io.FilterInputStream#in169*/170public final void readFully(byte b[]) throws IOException {171readFully(b, 0, b.length);172}173174/**175* See the general contract of the {@code readFully}176* method of {@code DataInput}.177* <p>178* Bytes179* for this operation are read from the contained180* input stream.181*182* @param b the buffer into which the data is read.183* @param off the start offset in the data array {@code b}.184* @param len the number of bytes to read.185* @throws NullPointerException if {@code b} is {@code null}.186* @throws IndexOutOfBoundsException if {@code off} is negative,187* {@code len} is negative, or {@code len} is greater than188* {@code b.length - off}.189* @throws EOFException if this input stream reaches the end before190* reading all the bytes.191* @throws IOException the stream has been closed and the contained192* input stream does not support reading after close, or193* another I/O error occurs.194* @see java.io.FilterInputStream#in195*/196public final void readFully(byte b[], int off, int len) throws IOException {197Objects.checkFromIndexSize(off, len, b.length);198int n = 0;199while (n < len) {200int count = in.read(b, off + n, len - n);201if (count < 0)202throw new EOFException();203n += count;204}205}206207/**208* See the general contract of the {@code skipBytes}209* method of {@code DataInput}.210* <p>211* Bytes for this operation are read from the contained212* input stream.213*214* @param n the number of bytes to be skipped.215* @return the actual number of bytes skipped.216* @throws IOException if the contained input stream does not support217* seek, or the stream has been closed and218* the contained input stream does not support219* reading after close, or another I/O error occurs.220*/221public final int skipBytes(int n) throws IOException {222int total = 0;223int cur = 0;224225while ((total<n) && ((cur = (int) in.skip(n-total)) > 0)) {226total += cur;227}228229return total;230}231232/**233* See the general contract of the {@code readBoolean}234* method of {@code DataInput}.235* <p>236* Bytes for this operation are read from the contained237* input stream.238*239* @return the {@code boolean} value read.240* @throws EOFException if this input stream has reached the end.241* @throws IOException the stream has been closed and the contained242* input stream does not support reading after close, or243* another I/O error occurs.244* @see java.io.FilterInputStream#in245*/246public final boolean readBoolean() throws IOException {247int ch = in.read();248if (ch < 0)249throw new EOFException();250return (ch != 0);251}252253/**254* See the general contract of the {@code readByte}255* method of {@code DataInput}.256* <p>257* Bytes258* for this operation are read from the contained259* input stream.260*261* @return the next byte of this input stream as a signed 8-bit262* {@code byte}.263* @throws EOFException if this input stream has reached the end.264* @throws IOException the stream has been closed and the contained265* input stream does not support reading after close, or266* another I/O error occurs.267* @see java.io.FilterInputStream#in268*/269public final byte readByte() throws IOException {270int ch = in.read();271if (ch < 0)272throw new EOFException();273return (byte)(ch);274}275276/**277* See the general contract of the {@code readUnsignedByte}278* method of {@code DataInput}.279* <p>280* Bytes281* for this operation are read from the contained282* input stream.283*284* @return the next byte of this input stream, interpreted as an285* unsigned 8-bit number.286* @throws EOFException if this input stream has reached the end.287* @throws IOException the stream has been closed and the contained288* input stream does not support reading after close, or289* another I/O error occurs.290* @see java.io.FilterInputStream#in291*/292public final int readUnsignedByte() throws IOException {293int ch = in.read();294if (ch < 0)295throw new EOFException();296return ch;297}298299/**300* See the general contract of the {@code readShort}301* method of {@code DataInput}.302* <p>303* Bytes304* for this operation are read from the contained305* input stream.306*307* @return the next two bytes of this input stream, interpreted as a308* signed 16-bit number.309* @throws EOFException if this input stream reaches the end before310* reading two bytes.311* @throws IOException the stream has been closed and the contained312* input stream does not support reading after close, or313* another I/O error occurs.314* @see java.io.FilterInputStream#in315*/316public final short readShort() throws IOException {317int ch1 = in.read();318int ch2 = in.read();319if ((ch1 | ch2) < 0)320throw new EOFException();321return (short)((ch1 << 8) + (ch2 << 0));322}323324/**325* See the general contract of the {@code readUnsignedShort}326* method of {@code DataInput}.327* <p>328* Bytes329* for this operation are read from the contained330* input stream.331*332* @return the next two bytes of this input stream, interpreted as an333* unsigned 16-bit integer.334* @throws EOFException if this input stream reaches the end before335* reading two bytes.336* @throws IOException the stream has been closed and the contained337* input stream does not support reading after close, or338* another I/O error occurs.339* @see java.io.FilterInputStream#in340*/341public final int readUnsignedShort() throws IOException {342int ch1 = in.read();343int ch2 = in.read();344if ((ch1 | ch2) < 0)345throw new EOFException();346return (ch1 << 8) + (ch2 << 0);347}348349/**350* See the general contract of the {@code readChar}351* method of {@code DataInput}.352* <p>353* Bytes354* for this operation are read from the contained355* input stream.356*357* @return the next two bytes of this input stream, interpreted as a358* {@code char}.359* @throws EOFException if this input stream reaches the end before360* reading two bytes.361* @throws IOException the stream has been closed and the contained362* input stream does not support reading after close, or363* another I/O error occurs.364* @see java.io.FilterInputStream#in365*/366public final char readChar() throws IOException {367int ch1 = in.read();368int ch2 = in.read();369if ((ch1 | ch2) < 0)370throw new EOFException();371return (char)((ch1 << 8) + (ch2 << 0));372}373374/**375* See the general contract of the {@code readInt}376* method of {@code DataInput}.377* <p>378* Bytes379* for this operation are read from the contained380* input stream.381*382* @return the next four bytes of this input stream, interpreted as an383* {@code int}.384* @throws EOFException if this input stream reaches the end before385* reading four bytes.386* @throws IOException the stream has been closed and the contained387* input stream does not support reading after close, or388* another I/O error occurs.389* @see java.io.FilterInputStream#in390*/391public final int readInt() throws IOException {392int ch1 = in.read();393int ch2 = in.read();394int ch3 = in.read();395int ch4 = in.read();396if ((ch1 | ch2 | ch3 | ch4) < 0)397throw new EOFException();398return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));399}400401private byte readBuffer[] = new byte[8];402403/**404* See the general contract of the {@code readLong}405* method of {@code DataInput}.406* <p>407* Bytes408* for this operation are read from the contained409* input stream.410*411* @return the next eight bytes of this input stream, interpreted as a412* {@code long}.413* @throws EOFException if this input stream reaches the end before414* reading eight bytes.415* @throws IOException the stream has been closed and the contained416* input stream does not support reading after close, or417* another I/O error occurs.418* @see java.io.FilterInputStream#in419*/420public final long readLong() throws IOException {421readFully(readBuffer, 0, 8);422return (((long)readBuffer[0] << 56) +423((long)(readBuffer[1] & 255) << 48) +424((long)(readBuffer[2] & 255) << 40) +425((long)(readBuffer[3] & 255) << 32) +426((long)(readBuffer[4] & 255) << 24) +427((readBuffer[5] & 255) << 16) +428((readBuffer[6] & 255) << 8) +429((readBuffer[7] & 255) << 0));430}431432/**433* See the general contract of the {@code readFloat}434* method of {@code DataInput}.435* <p>436* Bytes437* for this operation are read from the contained438* input stream.439*440* @return the next four bytes of this input stream, interpreted as a441* {@code float}.442* @throws EOFException if this input stream reaches the end before443* reading four bytes.444* @throws IOException the stream has been closed and the contained445* input stream does not support reading after close, or446* another I/O error occurs.447* @see java.io.DataInputStream#readInt()448* @see java.lang.Float#intBitsToFloat(int)449*/450public final float readFloat() throws IOException {451return Float.intBitsToFloat(readInt());452}453454/**455* See the general contract of the {@code readDouble}456* method of {@code DataInput}.457* <p>458* Bytes459* for this operation are read from the contained460* input stream.461*462* @return the next eight bytes of this input stream, interpreted as a463* {@code double}.464* @throws EOFException if this input stream reaches the end before465* reading eight bytes.466* @throws IOException the stream has been closed and the contained467* input stream does not support reading after close, or468* another I/O error occurs.469* @see java.io.DataInputStream#readLong()470* @see java.lang.Double#longBitsToDouble(long)471*/472public final double readDouble() throws IOException {473return Double.longBitsToDouble(readLong());474}475476private char lineBuffer[];477478/**479* See the general contract of the {@code readLine}480* method of {@code DataInput}.481* <p>482* Bytes483* for this operation are read from the contained484* input stream.485*486* @deprecated This method does not properly convert bytes to characters.487* As of JDK 1.1, the preferred way to read lines of text is via the488* {@code BufferedReader.readLine()} method. Programs that use the489* {@code DataInputStream} class to read lines can be converted to use490* the {@code BufferedReader} class by replacing code of the form:491* <blockquote><pre>492* DataInputStream d = new DataInputStream(in);493* </pre></blockquote>494* with:495* <blockquote><pre>496* BufferedReader d497* = new BufferedReader(new InputStreamReader(in));498* </pre></blockquote>499*500* @return the next line of text from this input stream.501* @throws IOException if an I/O error occurs.502* @see java.io.BufferedReader#readLine()503* @see java.io.FilterInputStream#in504*/505@Deprecated506public final String readLine() throws IOException {507char buf[] = lineBuffer;508509if (buf == null) {510buf = lineBuffer = new char[128];511}512513int room = buf.length;514int offset = 0;515int c;516517loop: while (true) {518switch (c = in.read()) {519case -1:520case '\n':521break loop;522523case '\r':524int c2 = in.read();525if ((c2 != '\n') && (c2 != -1)) {526if (!(in instanceof PushbackInputStream)) {527this.in = new PushbackInputStream(in);528}529((PushbackInputStream)in).unread(c2);530}531break loop;532533default:534if (--room < 0) {535buf = new char[offset + 128];536room = buf.length - offset - 1;537System.arraycopy(lineBuffer, 0, buf, 0, offset);538lineBuffer = buf;539}540buf[offset++] = (char) c;541break;542}543}544if ((c == -1) && (offset == 0)) {545return null;546}547return String.copyValueOf(buf, 0, offset);548}549550/**551* See the general contract of the {@code readUTF}552* method of {@code DataInput}.553* <p>554* Bytes555* for this operation are read from the contained556* input stream.557*558* @return a Unicode string.559* @throws EOFException if this input stream reaches the end before560* reading all the bytes.561* @throws IOException the stream has been closed and the contained562* input stream does not support reading after close, or563* another I/O error occurs.564* @throws UTFDataFormatException if the bytes do not represent a valid565* modified UTF-8 encoding of a string.566* @see java.io.DataInputStream#readUTF(java.io.DataInput)567*/568public final String readUTF() throws IOException {569return readUTF(this);570}571572/**573* Reads from the574* stream {@code in} a representation575* of a Unicode character string encoded in576* <a href="DataInput.html#modified-utf-8">modified UTF-8</a> format;577* this string of characters is then returned as a {@code String}.578* The details of the modified UTF-8 representation579* are exactly the same as for the {@code readUTF}580* method of {@code DataInput}.581*582* @param in a data input stream.583* @return a Unicode string.584* @throws EOFException if the input stream reaches the end585* before all the bytes.586* @throws IOException the stream has been closed and the contained587* input stream does not support reading after close, or588* another I/O error occurs.589* @throws UTFDataFormatException if the bytes do not represent a590* valid modified UTF-8 encoding of a Unicode string.591* @see java.io.DataInputStream#readUnsignedShort()592*/593public static final String readUTF(DataInput in) throws IOException {594int utflen = in.readUnsignedShort();595byte[] bytearr = null;596char[] chararr = null;597if (in instanceof DataInputStream dis) {598if (dis.bytearr.length < utflen){599dis.bytearr = new byte[utflen*2];600dis.chararr = new char[utflen*2];601}602chararr = dis.chararr;603bytearr = dis.bytearr;604} else {605bytearr = new byte[utflen];606chararr = new char[utflen];607}608609int c, char2, char3;610int count = 0;611int chararr_count=0;612613in.readFully(bytearr, 0, utflen);614615while (count < utflen) {616c = (int) bytearr[count] & 0xff;617if (c > 127) break;618count++;619chararr[chararr_count++]=(char)c;620}621622while (count < utflen) {623c = (int) bytearr[count] & 0xff;624switch (c >> 4) {625case 0, 1, 2, 3, 4, 5, 6, 7 -> {626/* 0xxxxxxx*/627count++;628chararr[chararr_count++]=(char)c;629}630case 12, 13 -> {631/* 110x xxxx 10xx xxxx*/632count += 2;633if (count > utflen)634throw new UTFDataFormatException(635"malformed input: partial character at end");636char2 = (int) bytearr[count-1];637if ((char2 & 0xC0) != 0x80)638throw new UTFDataFormatException(639"malformed input around byte " + count);640chararr[chararr_count++]=(char)(((c & 0x1F) << 6) |641(char2 & 0x3F));642}643case 14 -> {644/* 1110 xxxx 10xx xxxx 10xx xxxx */645count += 3;646if (count > utflen)647throw new UTFDataFormatException(648"malformed input: partial character at end");649char2 = (int) bytearr[count-2];650char3 = (int) bytearr[count-1];651if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80))652throw new UTFDataFormatException(653"malformed input around byte " + (count-1));654chararr[chararr_count++]=(char)(((c & 0x0F) << 12) |655((char2 & 0x3F) << 6) |656((char3 & 0x3F) << 0));657}658default ->659/* 10xx xxxx, 1111 xxxx */660throw new UTFDataFormatException(661"malformed input around byte " + count);662}663}664// The number of chars produced may be less than utflen665return new String(chararr, 0, chararr_count);666}667}668669670