[네트워크 프로그래밍1]필터 입출력 스트림 정리
류명운
·2015. 4. 12. 22:58
1. FilterInputStream과 FilterOutputStream
FilterStream에 대해 배우기 전, 기반 스트림과 기반 보조스트림에 대한 개념을 잡아야 한다.
기반 스트림은 ①바이트 기반 스트림과 ②문자 기반 스트림으로 나뉘게 된다.
이러한 기반 스트림은 실제 데이터를 주고받는 스트림을 뜻한다. 실제로 데이터를 입출력할 수 있는 기능을 제공한다.
기반 보조스트림은 보조 스트림만으로는 입출력 처리를 할 수 없고, 기반 스트림을 먼저 생성한 다음에 이를 이용해서 보조 스트림을 생성하게 된다. 보조 스트림은 기반 스트림을 통하여 데이터를 입출력하며, 기반 스트림에서는 제공해주지 않는 여러 기능을 제공한다.
기반 보조스트림 또한, ①바이트 기반 보조스트림과 ②문자 기반 보조스트림으로 나뉘게 된다.
바이트 기반 보조스트림에 대해 더 자세히 알아보자.
다음 표에서 나오는 모든 보조 스트림은 InputStream과 OutputStream의 자손들이므로 입출력 방법이 같다.
이제 다시 본론으로 들어와 필터 입출력 클래스에 대해 자세히 알아보자.
필터 입출력 클래스란?-> 기반 스트림에 연결하여 바이트 데이터가 아닌, 문자, 정수, 실수 등과 같은 데이터를 직접 전송 할 수 있는 기능을 추가한 클래스들을 필터 입출력 클래스라 한다.
2. DataOutputStream과 DataInputStream
기반 스트림에 연결하여 정수, 문자 및 실수와 같이 자료형 별로 데이터를 전송하는 기능을 구현하는 클래스가 DataOutputStream 및 DataInputStream 클래스이다.
2.1 DataOutputStream 클래스
DataOutputStream 클래스는 FilterOutputStream 클래스의 하위 클래스이며 바이트 단위로 전송하는 write(int b)메소드 뿐만 아니라 부울 값, 정수, 실수, 문자 및 문자열과 같이 자료형별로 데이터를 전송하는 메소드를 포함한다.
- DataOutputStream 클래스 생성자 메소드
->public DataOutputStream(OutputStream out)
->생성자에서 보는 것처럼 인수로 연결하고자 하는 OutputStream(바이트 기반 스트림) 객체를 사용해야 한다.
DataOutputStream에 정의된 메소드 | 설명 |
synchronized void write(int b) throws IOException |
바이트 단위로 데이터를 전송 |
synchronized void write(byte[] data) throws IOException |
|
synchronized void write(byte[] data, int offset, int length) throws IOException |
|
final void writeBoolean(boolean v) throws IOException |
인수로 지정한 부울 값, 정수 및 실수를 전송 (big-endian 방식[리터럴에 있는 순서대로 쓰는 방식] boolean, byte->1byte short->2byte int, float->4byte long, double->8byte |
final void writeByte(int b) throws IOException |
|
final void writeShort(int s) throws IOException |
|
final void writeInt(int i) throws IOException |
|
final void writeLong(long i) throws IOException |
|
final void writeFloat(float f) throws IOException |
|
final void writeDouble(double d) throws IOException |
|
final void writeChar(int c) throws IOException | 문자를 전송, 2바이트로 표현하는 유니코드 사용 |
final void writeChars(String s) throws IOException | 문자열 s의 각 문자를 2바이트 유니코드로 전송 |
final void writeBytes(String s) throws IOException | 문자열 s에 있는 각 문자의 하위 바이트만을 전송 |
final void writeUTF(String s) throws IOException | 전송하고자하는 문자열의 길이와 함께 각 문자를 UTF-8 형식으로 인코딩하여 전송(0~65535 길이만 유효) |
* writeInt(int i)로 저장된 정수는 반드시 readInt() 메소드로 읽어야 하고 writeDouble(double d)로 저장된 실수는 반드시 readDouble() 메소드로 읽어야 한다. 다른 메소드도 마찬가지다.
*writeUTF("a"); -> 2byte
*writeChar(65); -> 대문자 'A'를 전송
* 필터 스트림과 같이 상위 수준에서 지원하는 readInt()를 포함한 메소드들은 부호가 있는 byte, short, 및 int 형의 정수 값을 반환하므로 -1은 유효한 데이터 값이다. 따라서 이러한 메소드는 스트림의 끝을 만나면 -1 대신에 EOFException 예외를 발생시킨다.
2.2 DataInputStream 클래스
DataInputStream 클래스는 FilterInputStream 클래스의 하위 클래스이며 바이트 단위로 데이터를 수신하는 read() 메소드 뿐만 아니라 부울 값, 정수, 실수, 문자 및 문자열과 같이 자료형별로 데이터를 수신하는 메소드를 포함한다.
- DataInputStream 클래스 생성자 메소드
->public DataInputStream(InputStream in)
DataInputStream에 정의된 메소드 | 설명 |
abstract int read(int) throws IOException | 바이트 단위로 데이터를 읽음 |
int read(byte[] data) throws IOException | |
int read(byte[] data, int offset, int length) throws IOException | |
final boolean readBoolean() throws IOException | 인수로 지정한 부울 값, 정수 및 실수를 읽음 (big-endian 방식[리터럴에 있는 순서대로 쓰는 방식] boolean, byte->1byte short->2byte int, float->4byte long, double->8byte |
final byte readByte() throws IOException | |
final short readShort() throws IOException | |
final int readInt() throws IOException | |
final long readLong() throws IOException | |
final float readFloat() throws IOException | |
final double readDouble() throws IOException | |
void readFully(byte[] data) throws IOException | write(byte[] data)에 대응하는 메소드 |
void readFully(byte[] data, int offset, int length) throws IOException | write(byte[], int offset, int length)에 대응하는 메소드 |
final char readChar() throws IOException | 문자를 읽음, 2바이트로 표현하는 유니코드 사용, 읽을 수 없다면 EOFException 예외 발생 |
final String readLine() throws IOException | 줄 단위로 문자열을 읽어옴 |
final String readUTF() throws IOException | writeUTF() 메소드가 저장한 문자열을 읽고 반환 |
final int readUnsignedByte() throws IOException | 부호가 없는 byte형(0~255)를 읽음 |
final int readUnsignedShort() throws IOException | 부호가 없는 short형(0~65,535)를 읽음 |
3. BufferedInputStream 및 BufferedOutputStream
->스트림의 입출력 효율을 높이기 위해 버퍼를 사용하는 보조 스티림(기반 스트림에 연결하여 데이터를 버퍼에 저장하였다가 버퍼가 꽉 차면 한 번에 스트림에 입출력하는 기능을 제공)
->한 바이트씩 입출력하는 것 보다 버퍼(바이트배열)를 사용해서 한 번에 여러 바이트를 입출력하는 것이 빠르기 때문에 대부분의 입출력 작업에 사용된다.
* 지연 현상을 예방할 수 있다.
3.1 BufferedOutputStream 클래스
->FilterOutputStream 클래스이기 때문에 생성자 메소드의 인수로 기반 스트림 클래스의 객체가 사용된다.
public BufferedOutputStream(OutputStream out) //버퍼 사이즈를 정해주지 않았기때문에 디폴트로 지정 |
public BufferedOutputStream(OutputStream out, int size) //size 만큼의 버퍼 사이즈를 가짐. |
메소드를 살펴보면 다음 아래와 같다.
메소드 |
설명 |
void write(int b) throws IOException |
바이트 데이터를 버퍼에 전송하였다가 버퍼가 다 차면 자동으로 한 번에 버퍼의 모든 데이터를 스트림으로 전송한다 |
void write(byte[] data, int offset, int length) throws IOException |
|
void flush() throws IOException |
버퍼가 다 차지 않았을 경우에 버퍼에 있는 데이터를 강제적으로 스트림으로 전송하게 하는 메소드이다 |
void close() throws IOException | flush()를 호출해서 버퍼의 모든 내용을 출력소스에 출력하고, BufferedOutputStream 인스턴스가 사용하던 모든 자원을 반환한다. |
버퍼가 가득 찼을때만 출력소스에 출력을 하기 때문에, 마지막 출력 부분이 출력소스에 쓰여지지 못하고, BufferedOutputStream의 버퍼에 남아있는 채로 프로그램이 종료될 수 있다는 점을 주의해야 한다.
그래서 프로그램에서 모든 출력 작업을 마친 후 BufferedOutputStream에 close()나 flush()를 호출해서 마지막에 버퍼에 있는 모든 내용이 출력소스에 출력되도록 해야 한다.
3.2 BufferedInputStream 클래스
->입력 스트림으로 부터 버퍼 크기만큼의 데이터를 읽어다 자신의 내부 버퍼에 저장한다. 그 후 프로그램에서는 BufferedInputStream의 버퍼에 저장된 데이터를 읽으면 되는 것이다. 외부의 입력 스트림으로 부터 읽는 것보다 내부의 버퍼로 읽는 것이 훨씬 빠르기 때문에 그 만큼 작업 효율이 높아진다.
public BufferedInputStream(InputStream in) //버퍼 사이즈를 정해주지 않았기때문에 디폴트로 지정 |
public BufferedInputStream(InputStream in, int size) //size 만큼의 버퍼 사이즈를 가짐. |
메소드를 살펴보면 다음 아래와 같다.
메소드 |
설명 |
int read() throws IOException |
한 바이트의 데이터를 읽어 정수형으로 버퍼에 반환 |
int read(byte[] data, int offset, int length) throws IOException |
data 바이트의 offset방부터 length만큼 읽어서 버퍼에 저장, 읽은 바이트의 갯수를 반환 |
int available() throws IOException |
available:구할 수 있는; 입력 스트림내에서 읽어올 수 있는 데이터의 수를 반환, 데이터가 없을 경우 0을 반환 읽어올 수 있는 데이터의 크기 만큼 byte 배열 선언해주기 ->byte[] data = new byte[System.in.available()]; |
long skip(long n) throws IOException |
입력 스트림내에서 n 바이트 수만큼 데이터를 스킵하고, 실제로 스킵한 바이트 수를 반환, 스트림의 끝을 만나면 -1을 반환 |
void mark(int readlimit) |
입력 스트림으로부터 데이터를 읽고 있을 때, 현재 읽고 있는 데이터에 마킹을 함 |
void rest() throws IOException |
마킹을 리셋하면 이전에 마킹한 데이터부터 다시 데이터를 읽음 |
boolean markSupported() |
마킹 기능의 지원유무를 알려준다 |
4. PrintStream 클래스
->PrintStream은 데이터를 기반 스트림에 다양한 형태로 출력할 수 있는 print, println, printf와 같은 메소드를 오버로딩(overloading)하여 제공한다.
->자바에서는 화면과 연결된 스트림 객체 System.out을 기본적으로 정의하므로 사용자는 별도의 스트림 객체를 생성하지 않고 System.out 객체를 사용하면 되는 것이다.
생성자를 살펴보면 다음과 같다.
생성자 |
설명 |
PrintStream(File file) |
지정된 출력스트림을 기반으로 하는 PrintStream 인스턴스를 생성한다. autoFlush의 값을 true로 하면 println 메소드가 호출되거나 개행문자가 출력될 때 자동으로 flush 된다. 기본값은 false이다 |
PrintStream(File file, String csn) |
|
PrintStream(OutputStream out) |
|
PrintStream(OutputStream out, boolean autoFlush) |
|
PrintStream(OutputStream out, boolean autoFlush, String encoding) |
|
PrintStream(String fileName) |
|
PrintStream(String fileName, String csn) |
|
PrintStream printf(String format, Object... args) | 정형화된(formatted) 출력을 가능하게 한다 |
메소드를 살펴보면 다음과 같다.
메소드 |
설명 |
|
void print(boolean b) |
void println(boolean b) |
인자로 주어진 값을 출력소스에 문자로 출력한다 println 메소드는 출력 후 줄 바꿈을 하고, print 메소드는 줄을 바꾸지 않는다 |
void print(char c) |
void println(char c) |
|
void print(char[] c) |
void println(char[] c) |
|
void print(double d) |
void println(double d) |
|
void print(float f) |
void println(float f) |
|
void print(int i) |
void println(int i) |
|
void print(long l) |
void println(long l) |
|
void print(Object o) |
void println(Object o) |
|
void print(String s) |
void println(String s) |
|
void println() |
줄바꿈 문자(line separator)를 출력함으로써 줄을 바꾼다 |
5. PushbackInputStream 클래스
->데이터의 읽기 복구(unreading) 기능을 지원한다. 즉, read() 메소드에 의하여 스트림으로부터 읽은 데이터를 unread(int b) 메소드에 의하여 입력 스트림으로 다시 전송하여, 다음 read() 메소드를 통해 다시 읽혀질 수 있게 한다.
->디코더가 처리할 수 있는 이미지인지 결정하기 위해 읽어야할 데이터의 양이 고정되어 있다면 PushbackInputStream 클래스를 이용하여 같은 효과를 얻을 수 있다.
->한 바이트 크기의 푸시백 버퍼는 언어 스캐너를 구현할 때 단골처럼 사용된다.
생성자를 살펴보면 다음과 같다.
생성자 |
설명 |
PushbackInputStream(InputStream in) |
읽혀진 데이터를 다시 저장하는 버퍼 크기가 디폴트로 1인 스트림을 생성한다 |
PushbackInputStream(InputStrea in, int size) |
스트림의 버퍼 크기를 size만큼하여 생성한다 |
메소드를 살펴보면 다음과 같다.
메소드 |
설명 |
void unread(int b) throws IOException |
양의 정수 0~255 사이의 값을 스트림에 다시 저장한다 |
void unread(byte[] input) throws IOException |
인수로 주어진 input 바이트 배열의 내용을 스트림에 다시 저장한다 |
void unread(byte[] input, int offset, int length) throws IOException |
input 바이트 배열에서 offset 위치부터 length 개의 데이터를 스트림에 다시 저장한다 |
보다 자세한 사용은 다음과 같다.
..... PushbackInputStream pinput = new PushbackInputStream(InputStream in); int data = pinput.read(); // 한 바이트의 데이터를 읽는다. // 바이트를 검색하고, 경우에 따라서 다음과 같이 스트림에 pushback pinput.unread(data); // 스트림에 pushback int data = pinput.read(); // pushback된 데이터가 다시 읽혀진다. ..... |
p54. 연습문제
1. 예제 2.1에서 파일에 저장된 정수 500 다음에 문자열 "정수 및 실수를 저장한 내용입니다"를 추가로 덧붙여서 저장하는 클래스로 수정하시오.
2. 예제 2.2에서 저장한 파일의 내용을 읽어서 화면에 출력하는 클래스로 수정하시오.(예제 2.4를 예제 2.2에 포함시킴)
3. 예제 2.5에 "고객의 수" 레이블 및 텍스트 필드를 추가해서 고객의 수를 텍스트 필드에 추가하는 클래스로 수정하시오.
4. 예제 2.7에서 키보드로부터 읽는 내용을 example2_7.txt 파일에 저장하고 저장된 파일을 읽어서 화면에 출력하는 클래스로 수정하시오.
'삶의 늪에 들어 가기 전 > 정리중(미정리)' 카테고리의 다른 글
[한국성서대학교/한국성서대 묵상지] 7주차 묵상지 (2) | 2015.04.14 |
---|---|
[네트워크 프로그래밍1]파일 처리 클래스 정리 (0) | 2015.04.14 |
[네트워크 프로그래밍1]바이트 입출력 스트림 정리 (0) | 2015.04.12 |
봄 노래 리스트 (0) | 2015.04.10 |
[네트워크 프로그래밍1]텍스트 파일 생성(java, 이어쓰기, 입출력) (0) | 2015.04.08 |