바이트 기반의 보조 스트림의 자손: Data 입출력 스트림
1. DataInputStream과 DataOutputStream
- Filter 입출력 스트림의 자손이며 DataInput 인터페이스와 DataOutput의 인터페이스를 각각
구현한 보조 스트림이므로, byte 단위가 아닌 8가지 기본 자료형의 단위로 읽고 쓸 수 있다.
- 아래는 DataInputStream의 생성자와 메서드들을 설명한다.
(1) DataInputStream(InputStream in)
: InputStream의 인스턴스를 기반으로 하는 DataInputStream 인스턴스를 생성한다.
(2) 기본자료형 read기본자료형()
: 기본자료형에 해당 자료형을 넣으면 된다.
: 더 이상 읽을 값이 없다면 EOFException을 발생시킨다ㅣ
( ex) boolean readBoolean(), double readDouble() 등 )
(3) void readFully(byte[] b)
: 입력 스트림에서 지정된 배열의 크기만큼 읽어온다.
: 파일의 끝에 도달하면 EOFException이 발생하고, I/O에러가 발생하면 IOException n이 발생한다.
(4) void readFully(byte[] b, int off, int len)
: 입력 스트림에서 지정된 위치에서 len 만큼 데이터를 읽어온다.
: 파일의 끝에 도달하면 EOFException이 발생하고, I/O에러가 발생하면 IOException n이 발생한다.
(5) String readUTF()
: UFG-8 형식으로 쓰여진 문자를 읽는다.
: 더 이상 읽을 값이 없다면 EOFException 발생한다.
(6) static String readUTF(DataInput in)
: 입력 스트림(in)에서 UTF-8 형식의 유니코드를 읽어온다.
(7) int skipBytes(int n)
: 현재 읽고 있는 위치에서 지정된 숫자(n) 만큼을 건너뛴다.
- 아래는 DataOutputStream의 생성자와 메서드들을 설명한다.
(1) DataOutputStream(OutputStream out)
: OutputStream 의 인스턴스를 기반으로 하는 DataOutputStream인스턴스를 생성한다.
(2) void write기본자료형(기본자료형 약자)
: 각 자료형에 알맞은 값들을 출력한다.
(3) void writeUTF(String s)
: UTF 형식으로 문자를 출력한다.
(4) void writeChars(String s)
: 주어진 문자열을 출력한다.
: writeChar(int c) 메서드를 여러 번 호출한 결과와 같다.
(5) int size()
: DataOutputStream에 쓰여진 byte의 수를 알려준다.
1-1. Data 입출력 스트림을 이해하기 위한 예제(1)
( sample.dat를 열어보면 이진 데이터로 저장되므로 알 수 없는 숫자들이 있을 것이다. )
( 그러므로, UltraEdit과 같은 프로그램이나 앞서 했던 ByteArrayOutputStream을 사용하면
볼 수 있을 것이다. )
1-2. Data 입출력 스트림을 이해하기 위한 예제(2)
: 위에서 알아 볼 수 없는 이진 데이터를 자바에서 출력해보는 예제이다.
( 출력 값에서 [0, 0, 0, 10]은 writeInt(10)이고, [65, 96, 0, 0]은 writeFloat(20.0f),
[1]은 writeBoolean(true)이다. )
( 이 부분에서 result[i] < 0 일때 +256을 한 이유는 다음과 같다. )
( 1 byte에서 각 비트마다 1로 채워있다고 가정해보자. 그리고 제일 왼쪽 1bit가 부호로 지정되면,
값의 범위는 -128~127에 -1의 값을 가진다. 그러나 부호로 지정하지 않는다면 0~255 사이에 255의 값을 가진다. )
( 그래서 실제 범위(0~255)을 생각하면 -1은 255가 되어야 하므로 + 256을 해주는 것이다. )
1-3. Data 입출력 스트림을 이해하기 위한 예제(3)
: 위에서 만든 sample.dat을 자바에서 출력해보는 예제이다.
( 보통 문자들로 저장되어 파일들을 읽게 되는데, 그것을 int나 boolean으로 고칠려면
변환 과정이 필요하다. )
( 그러나, DataInputStream과 DataOutputStream을 사용함으로써 데이터를 변환할 필요도 없다. )
( 그냥 간단하게 자료형에 맞게 메서드를 사용하면 된다. )
1-4. Data 입출력 스트림을 이해하기 위한 예제(4)
: score.dat에 점수를 쓰는 예제이다.
( ex) score.dat에는 숫자 100이 00 00 00 64의 16진수로 저장되어 있다. )
1-5. Data 입출력 스트림을 이해하기 위한 예제(5)
: 예제(4)에서 만든 score.dat을 읽고 출력해보는 예제이다.
( readInt()는 더 이상 읽을 것이 없다면, EOFException이 발생한다. )
( 올바른 코드는 catch 마지막 뒤에 finally를 사용하여 dis.close()가 필요하다. )
( 그러나, 그렇게 되면 코드가 복잡해지기 때문에, try-with-resources문을 이용해서 close()를
자동 호출하도록 하면 간결해진다. )