[TIL] 2022년 9월 20일 화요일
3.3 DataInputStream과 DataOutputStream
- DataInputStream과 DataOutputStream은 각각 FilterInputStream, FilterOutputStream의 자식 클래스이자 DataInput, DataOutput 인터페이스를 구현
- DataInput과 DataOutput을 구현한 덕분에 이진 스트림에서 바이트를 읽고 이를 Java의 기본자료형으로, Java 기본 자료형에서 이진 스트림의 바이트로 재구성할 수 있음
자료형 | 메소드 | 설명 |
int | read(byte[] b) | Reads some number of bytes from the contained input stream and stores them into the buffer array b. |
int | read(byte[] b, int off, int len) | Reads up to len bytes of data from the contained input stream into an array of bytes. |
boolean | readBoolean() | See the general contract of the readBoolean method of DataInput. |
byte | readByte() | See the general contract of the readByte method of DataInput. |
char | readChar() | See the general contract of the readByte method of DataInput. |
double | readDouble() | See the general contract of the readChar method of DataInput. |
float | readFloat() | See the general contract of the readFloat method of DataInput. |
void | readFully(byte[] b) | See the general contract of the readFully method of DataInput. |
void | readFully(byte[] b, int off, int len) | See the general contract of the readFully method of DataInput. |
int | readInt() | See the general contract of the readInt method of DataInput. |
String | readLIne() | Deprecated.
This method does not properly convert bytes to characters.
|
long | readLong() | See the general contract of the readLongmethod of DataInput. |
short | readShort() | See the general contract of the readShortmethod of DataInput. |
int | readUnsignedByte() | See the general contract of the readUnsignedByte method of DataInput |
int | readUnsignedShort() | See the general contract of the readUnsignedShort method of DataInput. |
String | readUTF() | See the general contract of the readUTF method of DataInput. |
static String | readUTF(DataInput in) | Reads from the stream in a representation of a Unicode character string encoded in modified UTF-8 format; this string of characters is then returned as a String. |
int | skipBytes(int n) | See the general contract of the skipBytesmethod of DataInput. |
위 메소드 중 read 가 들어가는 메소드는 읽을 값이 없으면 EOFException이 발생한다. NPE처럼 줄여서 부르는 예외이름인 줄 알았는데 찾아보니 EOFException이란 말을 그대로 쓴다. End Of File, End Of Stream의 약자인 듯 하다. 입력받는 중에 기대와 다르게 파일이나 스트림의 끝에 도달했을 때 발생하는 오류이다. 사용할 때 예외처리하기보다 스트림의 끝에 특별한 값을 반환한다고 한다.
자료형 | 메소드 | 설명 |
void | flush() | Flushes this data output stream. |
int | size() | Returns the current value of the counter written, the number of bytes written to this data output stream so far. |
void | write(byte[] b, int off, int len) | Writes len bytes from the specified byte array starting at offset off to the underlying output stream. |
void | write(int b) | Writes the specified byte (the low eight bits of the argument b) to the underlying output stream. |
void | writeBoolean(boolean v) | Writes a boolean to the underlying output stream as a 1-byte value. |
void | writeByte(int v) | Writes out a byte to the underlying output stream as a 1-byte value. |
void | writeBytes(String s) | Writes out the string to the underlying output stream as a sequence of bytes. |
void | writeChar(int v) | Writes a char to the underlying output stream as a 2-byte value, high byte first. |
void | writeChars(String s) | Writes a string to the underlying output stream as a sequence of characters. |
void | writeDouble(double v) | Converts the double argument to a long using thedoubleToLongBits method in class Double, and then writes that long value to the underlying output stream as an 8-byte quantity, high byte first. |
void | writeFloat(float v) | Converts the float argument to an int using thefloatToIntBits method in class Float, and then writes that int value to the underlying output stream as a 4-byte quantity, high byte first. |
void | writeInt(int v) | Writes an int to the underlying output stream as four bytes, high byte first. |
void | writeLong(long v) | Writes a long to the underlying output stream as eight bytes, high byte first. |
void | writeShort(int v) | Writes a short to the underlying output stream as two bytes, high byte first. |
void | writeUTF(String str) | Writes a string to the underlying output stream usingmodified UTF-8 encoding in a machine-independent manner. |
import java.io.*;
import java.util.Arrays;
public class DataOutputStreamEx {
public static void main(String[] args) {
ByteArrayOutputStream bos = null;
DataOutputStream dos = null;
byte[] result = null;
try {
bos = new ByteArrayOutputStream();
dos = new DataOutputStream(bos);
dos.write(10);
dos.writeFloat(20.0f);
dos.writeBoolean(true);
result = bos.toByteArray();
String[] hex = new String[result.length];
for(int i=0; i< result.length; i++){
if(result[i]<0)
hex[i] = String.format("%02x", result[i] + 256);
else
hex[i] = String.format("%02x", result[i]);
}
System.out.println("10진수 : " + Arrays.toString(result));
System.out.println("16진수 : " + Arrays.toString(hex));
dos.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
교재 속 예제 15-9를 실행해봤는데 책과 결과가 달랐다. 책은 [0, 0, 0, 10, 65, -06, 0, 0, 1] /n [00, 00, 00, 0a, 41, a0, 00, 00, 01]이었다. 첫 줄부터 하나씩 비교하다보니 writeInt()라고 썼어야 했는데 write()라고만 썼다. 이 부분을 고치니 바로 해결할 수 있었다. 책을 보니 int와 float이 4byte라 ByteArrayOutputStream에 네 개의 공간을 차지한 듯 하다. 하지만 write()을 할 땐 10이 byte범위인 -128~127사이에 있어서 1byte만 차지한 것 같다. 궁금해서 write()메소드로 127을 출력해보니 127 그대로 출력하고 그 다음 128은 -128로 출력한다. 256은 0, 257은 1, 258은 2가 나왔다. write()로는 부호가 있는 byte범위의 정수만 입력할 수 있다.
import java.io.*;
public class DataOutputStreamEx2 {
public static void main(String[] args) {
int sum = 0;
int score = 0;
FileInputStream fis = null;
DataInputStream dis = null;
try {
fis = new FileInputStream("score.dat");
dis = new DataInputStream(fis);
while (true){
score = dis.readInt();
System.out.println(score);
sum += score;
}
}catch (EOFException ee){
System.out.printf("점수의 총합은 %d입니다.\n", sum);
}catch (IOException ie){
ie.printStackTrace();
}finally {
try {
if(dis != null)
dis.close();
}catch (IOException ie){
ie.printStackTrace();
}
}
}
}
import java.io.*;
public class DataOutputStreamEx2 {
public static void main(String[] args) {
int sum = 0;
int score = 0;
try (FileInputStream fis = new FileInputStream("score.dat");
DataInputStream dis = new DataInputStream(fis)) {
while (true){
score = dis.readInt();
System.out.println(score);
sum += score;
}
}catch (EOFException ee){
System.out.printf("점수의 총합은 %d입니다.\n", sum);
}catch (IOException ie){
ie.printStackTrace();
}
}
}
코드를 보다가 try - with - resource을 복습했다.