Friday, January 28, 2011

Java binary data process class DataInputStream

The good sample for binary data processing


1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 package java.io;
19
20 import org.apache.harmony.luni.internal.nls.Messages;
21 import org.apache.harmony.luni.util.Util;
22
23 /**
24 * Wraps an existing {@link InputStream} and reads typed data from it.
25 * Typically, this stream has been written by a DataOutputStream. Types that can
26 * be read include byte, 16-bit short, 32-bit int, 32-bit float, 64-bit long,
27 * 64-bit double, byte strings, and strings encoded in
28 * {@link DataInput modified UTF-8}.
29 *
30 * @see DataOutputStream
31 */
32 public class DataInputStream extends FilterInputStream implements DataInput {
33
34 byte[] buff;
35
36 /**
37 * Constructs a new DataInputStream on the InputStream {@code in}. All
38 * reads are then filtered through this stream. Note that data read by this
39 * stream is not in a human readable format and was most likely created by a
40 * DataOutputStream.
41 *
42 * @param in
43 * the source InputStream the filter reads from.
44 * @see DataOutputStream
45 * @see RandomAccessFile
46 */
47 public DataInputStream(InputStream in) {
48 super(in);
49 buff = new byte[8];
50 }
51
52 /**
53 * Reads bytes from this stream into the byte array {@code buffer}. Returns
54 * the number of bytes that have been read.
55 *
56 * @param buffer
57 * the buffer to read bytes into.
58 * @return the number of bytes that have been read or -1 if the end of the
59 * stream has been reached.
60 * @throws IOException
61 * if a problem occurs while reading from this stream.
62 * @see DataOutput#write(byte[])
63 * @see DataOutput#write(byte[], int, int)
64 */
65 @Override
66 public final int read(byte[] buffer) throws IOException {
67 return in.read(buffer, 0, buffer.length);
68 }
69
70 /**
71 * Reads at most {@code length} bytes from this stream and stores them in
72 * the byte array {@code buffer} starting at {@code offset}. Returns the
73 * number of bytes that have been read or -1 if no bytes have been read and
74 * the end of the stream has been reached.
75 *
76 * @param buffer
77 * the byte array in which to store the bytes read.
78 * @param offset
79 * the initial position in {@code buffer} to store the bytes
80 * read from this stream.
81 * @param length
82 * the maximum number of bytes to store in {@code buffer}.
83 * @return the number of bytes that have been read or -1 if the end of the
84 * stream has been reached.
85 * @throws IOException
86 * if a problem occurs while reading from this stream.
87 * @see DataOutput#write(byte[])
88 * @see DataOutput#write(byte[], int, int)
89 */
90 @Override
91 public final int read(byte[] buffer, int offset, int length)
92 throws IOException {
93 return in.read(buffer, offset, length);
94 }
95
96 /**
97 * Reads a boolean from this stream.
98 *
99 * @return the next boolean value from the source stream.
100 * @throws EOFException
101 * if the end of the filtered stream is reached before one byte
102 * has been read.
103 * @throws IOException
104 * if a problem occurs while reading from this stream.
105 * @see DataOutput#writeBoolean(boolean)
106 */
107 public final boolean readBoolean() throws IOException {
108 int temp = in.read();
109 if (temp < 0) {
110 throw new EOFException();
111 }
112 return temp != 0;
113 }
114
115 /**
116 * Reads an 8-bit byte value from this stream.
117 *
118 * @return the next byte value from the source stream.
119 * @throws EOFException
120 * if the end of the filtered stream is reached before one byte
121 * has been read.
122 * @throws IOException
123 * if a problem occurs while reading from this stream.
124 * @see DataOutput#writeByte(int)
125 */
126 public final byte readByte() throws IOException {
127 int temp = in.read();
128 if (temp < 0) {
129 throw new EOFException();
130 }
131 return (byte) temp;
132 }
133
134 /**
135 * Reads a 16-bit character value from this stream.
136 *
137 * @return the next char value from the source stream.
138 * @throws EOFException
139 * if the end of the filtered stream is reached before two bytes
140 * have been read.
141 * @throws IOException
142 * if a problem occurs while reading from this stream.
143 * @see DataOutput#writeChar(int)
144 */
145 private int readToBuff(int count) throws IOException {
146 int offset = 0;
147
148 while(offset < count) {
149 int bytesRead = in.read(buff, offset, count - offset);
150 if(bytesRead == -1) return bytesRead;
151 offset += bytesRead;
152 }
153 return offset;
154 }
155
156 public final char readChar() throws IOException {
157 if (readToBuff(2) < 0){
158 throw new EOFException();
159 }
160 return (char) (((buff[0] & 0xff) << 8) | (buff[1] & 0xff));
161
162 }
163
164 /**
165 * Reads a 64-bit double value from this stream.
166 *
167 * @return the next double value from the source stream.
168 * @throws EOFException
169 * if the end of the filtered stream is reached before eight
170 * bytes have been read.
171 * @throws IOException
172 * if a problem occurs while reading from this stream.
173 * @see DataOutput#writeDouble(double)
174 */
175 public final double readDouble() throws IOException {
176 return Double.longBitsToDouble(readLong());
177 }
178
179 /**
180 * Reads a 32-bit float value from this stream.
181 *
182 * @return the next float value from the source stream.
183 * @throws EOFException
184 * if the end of the filtered stream is reached before four
185 * bytes have been read.
186 * @throws IOException
187 * if a problem occurs while reading from this stream.
188 * @see DataOutput#writeFloat(float)
189 */
190 public final float readFloat() throws IOException {
191 return Float.intBitsToFloat(readInt());
192 }
193
194 /**
195 * Reads bytes from this stream into the byte array {@code buffer}. This
196 * method will block until {@code buffer.length} number of bytes have been
197 * read.
198 *
199 * @param buffer
200 * to read bytes into.
201 * @throws EOFException
202 * if the end of the source stream is reached before enough
203 * bytes have been read.
204 * @throws IOException
205 * if a problem occurs while reading from this stream.
206 * @see DataOutput#write(byte[])
207 * @see DataOutput#write(byte[], int, int)
208 */
209 public final void readFully(byte[] buffer) throws IOException {
210 readFully(buffer, 0, buffer.length);
211 }
212
213 /**
214 * Reads bytes from this stream and stores them in the byte array {@code
215 * buffer} starting at the position {@code offset}. This method blocks until
216 * {@code length} bytes have been read. If {@code length} is zero, then this
217 * method returns without reading any bytes.
218 *
219 * @param buffer
220 * the byte array into which the data is read.
221 * @param offset
222 * the offset in {@code buffer} from where to store the bytes
223 * read.
224 * @param length
225 * the maximum number of bytes to read.
226 * @throws EOFException
227 * if the end of the source stream is reached before enough
228 * bytes have been read.
229 * @throws IndexOutOfBoundsException
230 * if {@code offset < 0} or {@code length < 0}, or if {@code
231 * offset + length} is greater than the size of {@code buffer}.
232 * @throws IOException
233 * if a problem occurs while reading from this stream.
234 * @throws NullPointerException
235 * if {@code buffer} or the source stream are null.
236 * @see java.io.DataInput#readFully(byte[], int, int)
237 */
238 public final void readFully(byte[] buffer, int offset, int length)
239 throws IOException {
240 if (length < 0) {
241 throw new IndexOutOfBoundsException();
242 }
243 if (length == 0) {
244 return;
245 }
246 if (in == null) {
247 throw new NullPointerException(Messages.getString("luni.AA")); //$NON-NLS-1$
248 }
249 if (buffer == null) {
250 throw new NullPointerException(Messages.getString("luni.11")); //$NON-NLS-1$
251 }
252 if (offset < 0 || offset > buffer.length - length) {
253 throw new IndexOutOfBoundsException();
254 }
255 while (length > 0) {
256 int result = in.read(buffer, offset, length);
257 if (result < 0) {
258 throw new EOFException();
259 }
260 offset += result;
261 length -= result;
262 }
263 }
264
265 /**
266 * Reads a 32-bit integer value from this stream.
267 *
268 * @return the next int value from the source stream.
269 * @throws EOFException
270 * if the end of the filtered stream is reached before four
271 * bytes have been read.
272 * @throws IOException
273 * if a problem occurs while reading from this stream.
274 * @see DataOutput#writeInt(int)
275 */
276 public final int readInt() throws IOException {
277 if (readToBuff(4) < 0){
278 throw new EOFException();
279 }
280 return ((buff[0] & 0xff) << 24) | ((buff[1] & 0xff) << 16) |
281 ((buff[2] & 0xff) << 8) | (buff[3] & 0xff);
282 }
283
284 /**
285 * Returns a string that contains the next line of text available from the
286 * source stream. A line is represented by zero or more characters followed
287 * by {@code '\n'}, {@code '\r'}, {@code "\r\n"} or the end of the stream.
288 * The string does not include the newline sequence.
289 *
290 * @return the contents of the line or {@code null} if no characters were
291 * read before the end of the source stream has been reached.
292 * @throws IOException
293 * if a problem occurs while reading from this stream.
294 * @deprecated Use {@link BufferedReader}
295 */
296 @Deprecated
297 public final String readLine() throws IOException {
298 StringBuilder line = new StringBuilder(80); // Typical line length
299 boolean foundTerminator = false;
300 while (true) {
301 int nextByte = in.read();
302 switch (nextByte) {
303 case -1:
304 if (line.length() == 0 && !foundTerminator) {
305 return null;
306 }
307 return line.toString();
308 case (byte) '\r':
309 if (foundTerminator) {
310 ((PushbackInputStream) in).unread(nextByte);
311 return line.toString();
312 }
313 foundTerminator = true;
314 /* Have to be able to peek ahead one byte */
315 if (!(in.getClass() == PushbackInputStream.class)) {
316 in = new PushbackInputStream(in);
317 }
318 break;
319 case (byte) '\n':
320 return line.toString();
321 default:
322 if (foundTerminator) {
323 ((PushbackInputStream) in).unread(nextByte);
324 return line.toString();
325 }
326 line.append((char) nextByte);
327 }
328 }
329 }
330
331 /**
332 * Reads a 64-bit long value from this stream.
333 *
334 * @return the next long value from the source stream.
335 * @throws EOFException
336 * if the end of the filtered stream is reached before eight
337 * bytes have been read.
338 * @throws IOException
339 * if a problem occurs while reading from this stream.
340 * @see DataOutput#writeLong(long)
341 */
342 public final long readLong() throws IOException {
343 if (readToBuff(8) < 0){
344 throw new EOFException();
345 }
346 int i1 = ((buff[0] & 0xff) << 24) | ((buff[1] & 0xff) << 16) |
347 ((buff[2] & 0xff) << 8) | (buff[3] & 0xff);
348 int i2 = ((buff[4] & 0xff) << 24) | ((buff[5] & 0xff) << 16) |
349 ((buff[6] & 0xff) << 8) | (buff[7] & 0xff);
350
351 return ((i1 & 0xffffffffL) << 32) | (i2 & 0xffffffffL);
352 }
353
354 /**
355 * Reads a 16-bit short value from this stream.
356 *
357 * @return the next short value from the source stream.
358 * @throws EOFException
359 * if the end of the filtered stream is reached before two bytes
360 * have been read.
361 * @throws IOException
362 * if a problem occurs while reading from this stream.
363 * @see DataOutput#writeShort(int)
364 */
365 public final short readShort() throws IOException {
366 if (readToBuff(2) < 0){
367 throw new EOFException();
368 }
369 return (short) (((buff[0] & 0xff) << 8) | (buff[1] & 0xff));
370 }
371
372 /**
373 * Reads an unsigned 8-bit byte value from this stream and returns it as an
374 * int.
375 *
376 * @return the next unsigned byte value from the source stream.
377 * @throws EOFException
378 * if the end of the filtered stream has been reached before one
379 * byte has been read.
380 * @throws IOException
381 * if a problem occurs while reading from this stream.
382 * @see DataOutput#writeByte(int)
383 */
384 public final int readUnsignedByte() throws IOException {
385 int temp = in.read();
386 if (temp < 0) {
387 throw new EOFException();
388 }
389 return temp;
390 }
391
392 /**
393 * Reads a 16-bit unsigned short value from this stream and returns it as an
394 * int.
395 *
396 * @return the next unsigned short value from the source stream.
397 * @throws EOFException
398 * if the end of the filtered stream is reached before two bytes
399 * have been read.
400 * @throws IOException
401 * if a problem occurs while reading from this stream.
402 * @see DataOutput#writeShort(int)
403 */
404 public final int readUnsignedShort() throws IOException {
405 if (readToBuff(2) < 0){
406 throw new EOFException();
407 }
408 return (char) (((buff[0] & 0xff) << 8) | (buff[1] & 0xff));
409 }
410
411 /**
412 * Reads an string encoded in {@link DataInput modified UTF-8} from this
413 * stream.
414 *
415 * @return the next {@link DataInput MUTF-8} encoded string read from the
416 * source stream.
417 * @throws EOFException if the end of the input is reached before the read
418 * request can be satisfied.
419 * @throws IOException
420 * if a problem occurs while reading from this stream.
421 * @see DataOutput#writeUTF(java.lang.String)
422 */
423 public final String readUTF() throws IOException {
424 return decodeUTF(readUnsignedShort());
425 }
426
427
428 String decodeUTF(int utfSize) throws IOException {
429 return decodeUTF(utfSize, this);
430 }
431
432 private static String decodeUTF(int utfSize, DataInput in) throws IOException {
433 byte[] buf = new byte[utfSize];
434 char[] out = new char[utfSize];
435 in.readFully(buf, 0, utfSize);
436
437 return Util.convertUTF8WithBuf(buf, out, 0, utfSize);
438 }
439
440 /**
441 * Reads a string encoded in {@link DataInput modified UTF-8} from the
442 * {@code DataInput} stream {@code in}.
443 *
444 * @param in
445 * the input stream to read from.
446 * @return the next {@link DataInput MUTF-8} encoded string from the source
447 * stream.
448 * @throws IOException
449 * if a problem occurs while reading from this stream.
450 * @see DataOutputStream#writeUTF(java.lang.String)
451 */
452 public static final String readUTF(DataInput in) throws IOException {
453 return decodeUTF(in.readUnsignedShort(), in);
454 }
455
456 /**
457 * Skips {@code count} number of bytes in this stream. Subsequent {@code
458 * read()}s will not return these bytes unless {@code reset()} is used.
459 *
460 * This method will not throw an {@link EOFException} if the end of the
461 * input is reached before {@code count} bytes where skipped.
462 *
463 * @param count
464 * the number of bytes to skip.
465 * @return the number of bytes actually skipped.
466 * @throws IOException
467 * if a problem occurs during skipping.
468 * @see #mark(int)
469 * @see #reset()
470 */
471 public final int skipBytes(int count) throws IOException {
472 int skipped = 0;
473 long skip;
474 while (skipped < count && (skip = in.skip(count - skipped)) != 0) {
475 skipped += skip;
476 }
477 if (skipped < 0) {
478 throw new EOFException();
479 }
480 return skipped;
481 }
482 }

1 comment:

Anonymous said...

I've been surfing on-line more than three hours these days, yet I by no means discovered any fascinating article like yours. It's beautiful worth enough for me.

In my opinion, if all website owners and bloggers made good content
as you did, the net will be much more useful than ever before.


Here is my blog cedar finance minimum deposit